Unfortunately this is hard. The simplest way to implement this would be by checking on every remote call if the module is available and if the function is macro, which would considerably slow down the compiler. The reason why we have "require" is exactly so we don't need to pay this price. We could maybe add some sort of tracking back to the compiler, but that would be easier said than done.
One alternative approach we could do is to, instead of failing to compile for an undefined variable, we could warn, make it compile, and raise on said code path at runtime. Then some later pass would find this is a macro and warn, but now we are allowing a program that we are certain to fail, to compile and move forward.
Maybe there are other solutions but I can't think of anything else :(