Are Bitcoin transactions permitted to have no outputs (i.e. all inputs become transaction fee)?
No. If you create one, it won't be relayed or mined by Bitcoin Core. If it gets into a block, it will be rejected. From the source code for Bitcoin Core (tx_verify.cpp:164):

if (tx.vout.empty())
    return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");


However, you can create a vout with 0 satoshis. That isn't a "standard" transaction, so it will not be mined by the software by default. However, if it gets into a block, it's valid.