r.mapcalc has both exp(a,b) and pow(a,b), defined in xexp.c and xpow.c.

pow() works, but is only mentioned on the help page as an example in the
NULL support section.

Which is preferred? From looking at the code I assume exp(a,b) was an
add-on?

pow() is the add-on; it isn't present in the old r.mapcalc
(src/raster/r.mapcalc in 5.3).

The only difference I can tell is that exp(a,b) for forces DCELL output
while pow(a,b) will make a CELL map if both a,b are int.

exp() can take one or two arguments, while pow() always takes two.

pow() uses the "binary operator" type rules, i.e. the result is the
"highest" of either of the input types (where DCELL > FCELL > CELL).

exp() uses the "math function" type rules, i.e. it always returns
DCELL.

Should pow(a,b) be listed in the available fns or should one or the
other be tagged for future retirement?

pow() should certainly be included in the list of functions.

I don't see any need to retire either. pow() is a better version of
the two-argument form of exp(), but the two-argument form of exp() has
been around longer.