Yet another implementation enough compact and functional.
https://github.com/andry81/contools/tree/master/Scripts/Tools/std/echo_path_var.bat
echo_path_var.bat:
@echo off
rem USAGE:
rem   echo_path_var.bat <VAR> [<PREFIX> [<SUFFIX>]]
rem <VAR>: VALUE1;VALUE2;...;VALUEN
setlocal DISABLEDELAYEDEXPANSION
set "__?VAR__=%~1"
if not defined __?PREFIX__ set "__?PREFIX__=%~2"
if not defined __?SUFFIX__ set "__?SUFFIX__=%~3"
if not defined __?VAR__ exit /b 255
if not defined %__?VAR__% exit /b 1
rem Escape specific separator characters by sequence of `$NN` characters:
rem  1. `?` and `*` - globbing characters in the `for %%i in (...)` expression
rem  2. `,`, ` `    - separator characters in the `for %%i in (...)` expression
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%:$=$00!") do ( endlocal & set "%__?VAR__%=%%i" )
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%:^*=$01!") do ( endlocal & set "%__?VAR__%=%%i" )
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%:^?=$02!") do ( endlocal & set "%__?VAR__%=%%i" )
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%: =$03!") do ( endlocal & set "%__?VAR__%=%%i" )
rem escape tabulation character
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%:  =$04!") do ( endlocal & set "%__?VAR__%=%%i" )
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%:,=$05!") do ( endlocal & set "%__?VAR__%=%%i" )
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!%__?VAR__%!") do (
  endlocal
  for %%j in (%%i) do (
    set "__?LINE__=%%j"
    rem unescape
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$01=^*!") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$02=^?!") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$03= !") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$04=   !") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$05=,!") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?LINE__:$00=$!") do ( endlocal & set "__?LINE__=%%i" )
    rem trim leading white spaces
    rem setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims= " %%i in ("!__?LINE__!") do ( endlocal & set "__?LINE__=%%i" )
    setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?PREFIX__!!__?LINE__!!__?SUFFIX__!") do ( endlocal & echo.%%i)
  )
)
exit /b 0
echo_var.bat:
@echo off
rem USAGE:
rem   echo_var.bat <VAR> [<PREFIX> [<SUFFIX>]]
setlocal DISABLEDELAYEDEXPANSION
set "__?VAR__=%~1"
if not defined __?PREFIX__ set "__?PREFIX__=%~2"
if not defined __?SUFFIX__ set "__?SUFFIX__=%~3"
if not defined __?VAR__ exit /b 255
if not defined %__?VAR__% exit /b 1
rem safe echo
setlocal ENABLEDELAYEDEXPANSION & for /F "eol= tokens=* delims=" %%i in ("!__?PREFIX__!!%__?VAR__%!!__?SUFFIX__!") do ( endlocal & echo.%%i)
exit /b 0
Warning:
The eol=  actually is not empty and contains the 04 code character.
Examples:
1.
>
echo_path_var.bat PATH ` `
- To use with double quotes:
 
>
set __?PREFIX__=^"
set __?SUFFIX__=^"
echo_path_var.bat PATH
setlocal DISABLEDELAYEDEXPANSION
set AAA=123
rem with tabulation character
set BBB="?a/b/%%c%%!" ^;     "!d! ^; e ; f" ; ; ; !AAA! ^^; g,g ;;; h h
call "%%~dp0echo_var.bat" BBB ` `
call "%%~dp0echo_path_var.bat" BBB ` `
`"?a/b/%c%!" ;   "!d! ^; e ; f" ; ; ; !AAA! ^; g,g ;;; h h`
`"?a/b/%c%!" `
`        "!d! ^; e ; f" `
` `
` `
` !AAA! ^`
` g,g `
` h h`
- With globbing:
 
set "A=c:\windows\*.exe"
call "%%~dp0echo_var.bat A"
call "%%~dp0echo_path_var.bat A"
c:\windows\*.exe
c:\windows\bfsvc.exe
c:\windows\explorer.exe
c:\windows\fveupdate.exe
c:\windows\GSetup.exe
c:\windows\HelpPane.exe
c:\windows\hh.exe
c:\windows\notepad.exe
c:\windows\pfm.exe
c:\windows\ptsysexec.exe
c:\windows\pttestcmd.exe
c:\windows\py.exe
c:\windows\pyw.exe
c:\windows\regedit.exe
c:\windows\splwow64.exe
c:\windows\twunk_16.exe
c:\windows\twunk_32.exe
c:\windows\winhlp32.exe
c:\windows\write.exe
set "A=c:\windows\??.exe"
call "%%~dp0echo_var.bat A"
call "%%~dp0echo_path_var.bat A"
c:\windows\??.exe
c:\windows\hh.exe
c:\windows\py.exe
Pros:
- Use the 
for %%i in (...) statement to parse a path list value to parse VALUE;VALUE the same way as "VALUE";"VALUE". 
- Prints spaces and tabulation characters as is.
 
- Ignores sequence of 
; (ex: ;;;) and treats it a single character. 
- Can be used with globbing by default (in windows a path should not contain 
* and ? characters). 
Cons:
- Because 
!VAR:*=...! expression does not work as expected, and *, ? are globbing characters, then a string with * and ? characters must be in preformatted form: 1 * 2 ? 3 -> 1 ^* 2 ^? 3 
- Needs to separately trim leading and trailing white space characters.