Is using utility functions a bad practice?
No.
Even if you had named your original function useFormatMoney, it wouldn't have been a hook. It would have looked like a hook, and you might have used it like a hook, but it still would have been an ordinary function.
You could instead write a hook that returns a function
const useFormatMoney = () => {
const user = useUserContext()
return (value) => value == null ? '' : user.currency + value.toFixed(2)
}
This can be called unconditionally, and then the resulting function can be called conditionally. It is a much easier change, you can even keep the name formatMoney at the call sites.
N.b. a refactor is a change in code which keeps the observable behaviour the same, which is not the case here, the new requirement needs a change in behaviour.