Working with WordML is tricky. One tip when converting arbitrary XML to WordML using XSLT is to not worry about the text runs when processing blocks, but to instead create a template that matches text() nodes directly, and create the text runs there. It turns out that Word doesn't care if you nest text runs, which makes the problem much easier to solve.
<xsl:template match="text()" priority="1">
<w:r>
<w:t>
<xsl:value-of select="."/>
</w:t>
</w:r>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="para">
<w:p>
<xsl:apply-templates select="text() | *" />
</w:p>
</xsl:template>
<xsl:template match="b">
<w:r>
<w:rPr>
<w:b />
</w:rPr>
<w:t><xsl:apply-templates /></w:t>
</w:r>
</xsl:template>
This avoids the bad XSLT technique of inserting tags directly as escaped text. You'll end up with the bold tag as a nested text run, but as I said, Word couldn't care less. If you use this technique, you'll need to be careful to not apply templates to the empty space between paragraphs, since it will trigger the text template and create an out-of-context run.