Decorators with and without arguments
Your _patchfs and wrap_patchfs functions are virtually identical.  You don’t need the _patchfs version, just the internal one.  One function instead of two is easier to maintain:

def patchfs(_func=None, *, 
            additional_skip_names=None,
            modules_to_reload=None,
            modules_to_patch=None,
            allow_root_user=True):
    """Your docstring here ..."""

    def wrap_patchfs(f):
        @functools.wraps(f)
        def wrapped(*args, **kwargs):
            with Patcher(
                    additional_skip_names=additional_skip_names,
                    modules_to_reload=modules_to_reload,
                    modules_to_patch=modules_to_patch,
                    allow_root_user=allow_root_user) as p:
                kwargs['fs'] = p.fs
                return f(*args, **kwargs)

        return wrapped

    if _func:
        if not callable(_func):
            raise TypeError("Decorator argument not a function.\n"
                            "Did you mean `@patchfs(additional_skip_names=...)`?")
        return wrap_patchfs(_func)

    return wrap_patchfs


The if not callable: ... ensures you don’t accidentally try to use @patchfs(names_to_skip).  Using * forces the remaining arguments to keyword only arguments; you cannot just list the four arguments, which makes the decorator a little less error-prone. 



Your docstring's Usage:: examples lack the required def keywords for defining functions.