Yeah, this isn't going to be a trivial problem to solve. pd.read_excel accepts **kwargs in its signature. This means that you can pass whatever keyword arguments you please, because read_excel is not going to do anything with keyword arguments that it doesn't need to use.
One way of approaching this problem is to 
- Determine what keyword arguments read_excelactually accepts
- Build an argument list for read_excel
- Filter out invalid arguments based on the results of (1)
- Pass the filtered argument list to the function
To handle (1), you can use the inspect module to determine what arguments pd.read_excel accepts. In particular, the inspect.signature method returns a Signature object from which you may query the parameters attribute. This returns a mappingproxy (effectively an immutable dictionary).
import inspect
args = inspect.signature(pd.read_excel).parameters
print(args)
mappingproxy({'convert_float': <Parameter "convert_float=True">,
              'converters': <Parameter "converters=None">,
              'date_parser': <Parameter "date_parser=None">,
              'dtype': <Parameter "dtype=None">,
              ...})
Here, it is assumed (2) is already done. However, in your case, you will need to ensure your potential parameters are inside a dictionary, as this will make it really easy to intersect on the mappingproxy and filter. 
params = {'io' : 'myfile.xlsx', 'some_dummy_param' : True}
Step (3) involves performing a set intersection on the keys, and then rebuilding a new parameter list only from the intersection. 
valid_params = {k : params[k] for k in params.keys() & args.keys()}
print(valid_params)
{'io': 'myfile.xlsx'}
This forms your valid argument list—the basis for (4). 
df = pd.read_excel(**valid_params)