The only solution I can think of (and it's not a very good one), is to prefix the name of the required fields with some special suffix like req_, and then you could use formulas like this:
count((//*[not(*)] | //@*)[not(name() = "xml:lang")][starts-with(local-name(), 'req_')])
count((//*[not(*)] | //@*)[not(name() = "xml:lang")][starts-with(local-name(), 'req_')][. != ''])
This has the obvious drawback of giving you some somewhat unpleasant looking field names, and would make it hard to change which fields are and aren't required later (while still maintaining this design), so I would advise caution.