@joepk and @Evie Lapalme, unfortunately the amount of attributes are not known and are definitely greater than the 6 I posted - the screenshot of the spreadsheet above was a dummy/testing one, the real one would be a couple hundred rows, all with different combination of different values strung together for the Feature Description.
AttributeExposer would do the trick but I couldn't see a way to dynamically expose attributes, and could only see ways to expose attributes manually by typing them in, and only if the attribute name is already known. Ideally I would like AttributeExposer to be able to dynamically expose by accepting an @Value() input.
@ctredinnick , TCLCaller worked an absolute treat - it did exactly what I expected the output to be if AttributeCreator could somehow expose the values. However, as you mentioned it being deprecated soon, I've been looking at other more future-proof methods.
I managed to solve the issue by using PythonCaller to replicate the functionality of TCLCaller, and I modified my spreadsheet slightly just for ease of input:

And in the PythonCaller:
import fme
import fmeobjects
import re
def makeDescription(feature):
featureDesciption_Input = feature.getAttribute('Feature Description')
fdSplit = re.split('(\W)', featureDesciption_Input)
previousValue = ""
featureDesciption_Output = ""
for f in fdSplit:
word = f
if previousValue == "$":
word = feature.getAttribute(f)
if word != "$":
featureDesciption_Output = featureDesciption_Output + word
previousValue = f
featureDesciption_Output = featureDesciption_Output.replace(" - - "," - ")
featureDesciption_Output = featureDesciption_Output.replace(" - ","")
featureDesciption_Output = featureDesciption_Output.replace(" - ","")
feature.setAttribute('_description', featureDesciption_Output)
And I get the intended output in _description:
Thanks everyone for the suggestions and ideas.