A long time ago, everything in Tcl was stored internally as a string, including lists. Whitespace was chosen to separate list elements so they could be distinguished from each other later...
set planets [list "mercury" "venus" "march"] ;# stored in planets as "mercury venus march"
puts [lindex $planets 2] ;# lindex treats it's first (string) argument as a list, and splits on whitespace to find the third element
...but then some way to escape/quote whitespace characters was needed to be able to store these in the actual list elements. {
and }
were used for this...
set programs [list "hello world" "primes"] ;# stored in programs as "{hello world} primes"
...and now you need to be able to escape {
and }
, etc.
In modern Tcl versions, lists are stored more efficiently internally, but from the script writers point of view it's still stored that way for backwards compability and maybe for other reasons. So when you use a list as a string, you get this string representation of the list, with spaces, braces and backslashes.
The simple solution to your question is to never treat a list as a string, i.e. don't send a list as an argument where the command expects a string. Then you'll never see any special escape sequences unless you actually put them in an element.
puts $mylist ;# bad unless used for debugging
puts [join $mylist] ;# good
And don't treat strings as lists either:
set mystring "word1 {hello word3"
puts [lindex $mystring 1] ;# will throw an error
puts [lindex [split $mystring] 1] ;# good