I wouldn't allow the "default" or lowest precedence/priority matching template to silently swallow vowels or to do any other meaningful application processing.
It is a good practice that the template for all otherwise unmatched nodes (of a given kind), should produce a good debugging message and, optionally, terminate processing.
If this recommended practice isn't followed, then quite some errors will go silently unnoticed and it would be very difficult to find them and fix in any given fixed period of time.
Here is a solution, which involes only one empty template:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:vowels>
<c>A</c>
<c>E</c>
<c>I</c>
<c>O</c>
<c>U</c>
</my:vowels>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c[not(. = document('')/*/my:vowels/*)]"/>
</xsl:stylesheet>
When this transformation is performed on the following XML document:
<alphabet>
<c>A</c>
<c>B</c>
<c>C</c>
<c>D</c>
<c>E</c>
<c>F</c>
<c>G</c>
<c>H</c>
<c>I</c>
<c>J</c>
<c>K</c>
<c>L</c>
<c>M</c>
<c>N</c>
<c>O</c>
<c>P</c>
<c>Q</c>
<c>R</c>
<c>S</c>
<c>T</c>
<c>U</c>
<c>V</c>
<c>W</c>
<c>X</c>
<c>Y</c>
<c>Z</c>
</alphabet>
the wanted result is produced:
<alphabet>
<c>A</c>
<c>E</c>
<c>I</c>
<c>O</c>
<c>U</c>
</alphabet>