It'd be better if you showed us sample input XML and output XML. Without that, one might guess that @display_value in the input XML has more white space than you'd like. You could use normalize-space() when you define letter:
<xsl:variable name="letter">
<xsl:value-of select="normalize-space(@display_value)"/>
</xsl:variable>
or when you use it:
<xsl:value-of select="normalize-space($letter)"/>
Note, however, that normalize-space() is not the same as trim in other languages in that it will reduce repetitive whitespace internal to a string, not just on its ends.
See also "How to Trim in XSLT".
Update per new comment from OP:
Another possibility (apparently the reason in this case) is that the context into which $letter is output has significant white space that one is mistakenly attributing to $letter itself. Changing this:
[
<xsl:value-of select="$letter"/>
]
to this:
<xsl:text>[</xsl:text>
<xsl:value-of select="$letter"/>
<xsl:text>]</xsl:text>
helped resolve the problem.