In reply to Chris Hemedinger.

As a more complete source for library engines where VLIBNAM might hide the engine of concatenation level=2+, perhaps the appropriate engine in a "multi-library-engine scenario" would only be revealed for particular members with the ATTRC() function. We can signal this in %getEngine without adding to the parameter list. When the parameter is just a LIBNAME, the current solution using SASHELP.VLIBNAM provides the answer, but when it is a LIBNAME.MEMNAME, then the ATTRC() function would be relevant.
So (with interesting results) I tried :
%macro getEngine( param )/des='library or member engine' ;
%if %scan( &param, 2, . ) EQ %str() %then %do ;
%let dsid = %sysfunc( open( sashelp.vlibnam(
where=( libname EQ "%upcase(&param)" )), i )) ;
%if &dsid %then %do ;
%let engnum=%sysfunc( varnum( &dsid, ENGINE )) ;
%let rc= %sysfunc( fetch( &dsid )) ;
%sysfunc( getvarc( &dsid, &engnum ))
%let rc= %sysfunc( close( &dsid )) ;
%end ;
%end ;
%else %do ;
%let dsid = %sysfunc( open( &param, i )) ;
%if &dsid %then %do ;
%sysfunc( attrc( &dsid, ENGINE ))
%let rc= %sysfunc( close( &dsid )) ;
%end ;
%end ;
%mend getEngine ;
%LET LIB= SAShelp ;
%put library &lib uses engine %getEngine(&lib) ;
%put member vmacro uses engine %getEngine(sashelp.VMACRO) ;

This revealed that a VIEW night have a different engine from the library.
There is another type of VIEW created in a data step, like:
data a dataA dataB /view=a;
run;
%put the engine for dataset dataA is %getEngine(work.dataA) ;
%put the engine for a datastep view is %getEngine(work.A) ;
%put the engine for dataset dataB is %getEngine(work.dataB) ;

Only when the datastep VIEW was opened did the datasets defined on the DATA statement get created
I chose not to %UPCASE() the MEMNAME, because with SAS/Access engines, the value is preserved in many of the dictionary tables.
.... fun with SAS