In 2015 a patch to the mercurial-devel mailing list suggested adding an option to the commit command, called --allow-empty (much like the similar git option). However, it was decided to go with a configuration option instead.
This ended up being added in Mercurial 3.5 in 2015 July, by the name ui.allowemptycommit. One doesn't have to specify it in a user's or repo's configuration file however, it is sufficient to add a --config switch to a single command, like this:
hg ci -m "empty commit" --config ui.allowemptycommit=1
Additionally, in 2020 it was suggested for the hg rebase extension command to consider the value of another, experimental configuration option. It is named rewrite.empty-successor, and can be set to either skip (the default) or keep. The configuration option itself was introduced with Mercurial 5.5 in 2020 August, although I am not sure when the rebase extension started to consider it.
How it works seems to be that rebase reads the new option and then locally overrides the older ui.allowemptycommit option depending on whether rewrite.empty-successor is configured to skip or keep. The result is that the rebase extension of older Mercurial versions directly observes the ui.allowemptycommit=1 option (version 4.8.2 tested), while the newer versions' extension observes rewrite.empty-successor=keep instead (version 6.1 tested). The newer versions ignore the external state of the ui.allowemptycommit configuration.
Therefore to get hg rebase to keep empty changesets somewhat portably, both options can be set so as to keep them, like in this example:
hg rebase --config rewrite.empty-successor=keep --config ui.allowemptycommit=1 ...
My use case for all of this is to use hg convert on an svn repo, then use an empty hg commit to become the initial commit (local changeset number 0). Then I will use hg rebase first to make the soon-to-be changeset 0 the parent of the first imported svn revision (so it will become local changeset number 1, matching the svn revision number), and second to fix a certain problematic commit that hg convert doesn't parse correctly. It is crucial to me that the hg rebase commands should keep empty commits, such as those based on svn revisions which only changed directories. (Directories are never tracked by Mercurial on their own, only files.)