A fuga está funcionando, exceto que você não está escapando com frequência suficiente.
Com seu código, você deve escapar duas vezes: uma vez para o comando SET e uma segunda vez para o ECHO. O código para o SET tem escapa dupla. Após a execução, o valor do teste conterá as únicas fugas para que o ECHO funcione corretamente.
SET test=^^<foo^^>^^<bar what="cat"^^>^^</foo^^>
ECHO %test%
Você pode conviver com escapa simples se ECO o valor diretamente:
ECHO test=^<foo^>^<bar what="cat"^>^</foo^>
Ou se você usar a expansão atrasada:
setlocal enableDelayedExpansion
SET test=^<foo^>^<bar what="cat"^>^</foo^>
ECHO !test!
Você pode eliminar todas as fugas se você colocar a atribuição entre aspas:
setlocal enableDelayedExpansion
SET "test=<foo><bar what="cat"></foo>"
ECHO !test!
Lembre-se de que, no exemplo acima, "cat" não é mais citado durante a atribuição, então você teria que escapar de todos os caracteres suspeitos que possam aparecer lá.
Se você tiver muito texto para escrever, talvez valha a pena usar meu utilitário PrintHere.bat que emula o unix aqui documentar recurso. Supondo que você tenha PrintHere.bat em uma pasta que aparece dentro do seu PATH, então você pode usar:
call PrintHere :test
<foo><bar what="cat"></foo>
:test