[Question]
  [
[We already now how to strip a string from its spaces.](https://codegolf.stackexchange.com/q/50510/71426)
However, as proper gentlemen/ladies, we should rather *undress* it.
---
Undressing a string is the same as stripping it, only more delicate. Instead of removing all leading and trailing spaces at once, we remove them *one by one*. We also *alternate* between leading and trailing, so as not to burn steps.
Example, starting with `" codegolf "` (five leading and trailing spaces):
```
     codegolf     
    codegolf     
    codegolf    
   codegolf    
   codegolf   
  codegolf   
  codegolf  
 codegolf  
 codegolf 
codegolf 
codegolf
```
---
1. First output the string unchanged. Then, output every step. Begin by removing a *leading* space (if applicable - see rule #2).
2. The input may have a different number of leading and trailing spaces. If you run out of spaces on one side, keep undressing the other until the string is bare.
3. The input may have no leading nor trailing spaces. If that's the case, output it as-is.
4. Use [PPCG's default I/O methods](https://codegolf.meta.stackexchange.com/q/2447/71426). [PPCG Default loopholes](https://codegolf.meta.stackexchange.com/q/1061/71426) are forbidden.
5. Undefined behaviour on empty input, or input that only contains spaces, is OK.
6. You can assume that the string will only contain characters from the ASCII printable space (`0x20` to `0x7E`).
---
Examples - spaces are replaced by dots `.` for better readability:
```
4 leading spaces, 5 trailing: "....Yes, Sir!....."
....Yes, Sir!.....
...Yes, Sir!.....
...Yes, Sir!....
..Yes, Sir!....
..Yes, Sir!...
.Yes, Sir!...
.Yes, Sir!..
Yes, Sir!..
Yes, Sir!.
Yes, Sir!
6 leading, 3 trailing: "......Let's go golfing..."
......Let's go golfing...
.....Let's go golfing...
.....Let's go golfing..
....Let's go golfing..
....Let's go golfing.
...Let's go golfing.
...Let's go golfing
..Let's go golfing
.Let's go golfing
Let's go golfing
0 leading, 2 trailing: "Hello.."
Hello..
Hello.
Hello
0 leading, 0 trailing: "World"
World
21 leading, 5 trailing: ".....................a....."
.....................a.....
....................a.....
....................a....
...................a....
...................a...
..................a...
..................a..
.................a..
.................a.
................a.
................a
...............a
..............a
.............a
............a
...........a
..........a
.........a
........a
.......a
......a
.....a
....a
...a
..a
.a
a
```
A gentleman/lady is concise, so *the shortest answer in bytes wins*.
  
[Answer]
## [Retina](https://github.com/m-ender/retina), 26 bytes
```
{m`^ (.+)\z
$&¶$1
 $
 ¶$%`
```
[Try it online!](https://tio.run/##K0otycxL/K@qkRAXo6ddA8QqXCp6aipaCv@rcxPiFDT0tDVjqrhU1A5tUzHkUlDhUgAyVBP@a7oncKkC5bVrFGA69LiCE1T@64FAcn5Kanp@ThqYwwUiIlOLdRSCM4sUEUJ6ej6pJerFCun5CiC1mXnpIBmP1JycfCAdnl@UkwIA "Retina – Try It Online") (Test suite uses periods for clarity. The footer and header convert them to and from spaces for the main code.)
### Explanation
It would be nice if we could just alternate between dropping a leading and a trailing space and printing the intermediate result each time. The problem is that currently Retina can't print conditionally, so it would even print this intermediate result if there are no leading or no trailing spaces left, generating duplicates. (Retina 1.0 will get an option that only prints the result if the string was changed by the operation, but we're not there yet...)
So instead, we're building up a single string containing all intermediate results and printing that at the end.
```
{m`^ (.+)\z
$&¶$1
```
The `{` wraps both stages of the program in a loop which repeats until the string stops changing (which means there are no leading/trailing spaces left). The stage itself matches a leading space on the final line of the string, and that final line, and then writes back the match, as well as the stuff after the space on a new line (thereby dropping the leading space in the copy).
```
 $
 ¶$%`
```
Removing the trailing space is a bit easier. If we just match the final space, we can access the stuff in front of it (on the same line) with `$%`` which is a line-aware variant of the prefix substitution `$``.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~122~~ ~~107~~ ~~103~~ ~~102~~ ~~98~~ ~~95~~ ~~93~~ ~~91~~ ~~90~~ ~~88~~ 87 bytes
```
s=input()+' '
a=0
while-a*s!=id:
 if a:id=s
 a=~a
 if'!'>s[a]:s=s[1+a:len(s)+a];print s
```
[Try it online!](https://tio.run/##JcjBCsIwDADQe78iO2WzCM5jJfuRsUOw3RYobTEd4sVfrwzf8ZVP3XO6t6YkqRy1HywCGqabee8Sw5Uv2pF4Z0BWYCee1ADTl8/ADiedeXFKOo@WXQyp18Hy8igvSRW0NYTTM/uw5bjCH/4A "Python 2 – Try It Online")
---
# [Python 3](https://docs.python.org/3/), ~~97~~ ~~95~~ ~~93~~ 90 bytes
```
s=input()
a=p=print
p(s)
while s!=a:
 a=s
 if'!'>s:s=s[1:];p(s)
 if'!'>s[-1]:s=s[:-1];p(s)
```
[Try it online!](https://tio.run/##NYo7CoAwEAX7PcVaqYVFsIusFxGL4DcgyeJGxNNHjTjV8ObxFVbv6hiFrOMjFCUYYuLdugBcSAnnarcJJSOjAQ0JoJ3zLG9FC0mndN@k2792lepT0Y@kFCO@DH6cFr/N@HED "Python 3 – Try It Online")
[Answer]
# [Perl 6](https://perl6.org), 55 bytes
*Saved 3 bytes thanks to @nwellnhof.*
```
{($_,{$++%2??S/" "$//!!S/^" "//}...*)[^.comb*2].unique}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJKmYKvwv1pDJV6nWkVbW9XI3j5YX0lBSUVfX1ExWD8OyNTXr9XT09PSjI7TS87PTdIyitUrzcssLE2t/W/NpZKmoaQAAsn5Kanp@TlpCkqaermJBRpaemm5JRrqNarFNeqaesWJlZrW/wE "Perl 6 – Try It Online")
**Explanation**: `($_,{$++%2??S/" "$//!!S/^" "//}...*)` is a recursive infinite sequence that starts with the original string (`$_`) and the next element is given by the block called on the previous element.
The block itself gets the string in the `$_` variable. The operator `S/(regex)/(string)/` will search for the first occurence of `(regex)` in `$_`, replaces it with `(string)`, and returns the result. If there is no match, it returns the content of `$_` unchanged. We use the ternary operator `?? !!` with the condition `$++%2`, which alternates between `False` and `True` (`$` is a free variable that conserves its contents across calls to the block.) 
In the worst case (all spaces on one side and 1 other character), we remove 1 space every 2 steps. So we can be sure that in 2\*(length of the string) steps, all spaces will have been removed. We take that many elements from the recursive sequence with `[^.comb*2]` and finally discard duplicates (which occur whenever a space should have been removed but it isn't there) with `.unique`. This returns the list of strings, progressively stripped of spaces.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~21~~ 15 bytes
```
=v¬ðQi¦=}¤ðQi¨=
```
[Try it online!](https://tio.run/##MzBNTDJM/f/ftuzQmsMbAjMPLbOtPbQEzFph@/@/Ahj4pJaoFyuk5wNRTlpmXjpQCAA "05AB1E – Try It Online")
**Explanation**^
```
=                 # print input
 v                # for each character in input
  ¬ðQi  }         # if the first char in the current string is a space
      ¦=          # remove it and print without popping
         ¤ðQi     # if the last char in the current string is a space
             ¨=   # remove it and print without popping
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~89~~ 84 bytes
Recursive version is shorter ;-)
```
j;f(char*s){puts(s);*s^32||puts(++s);s[j=strlen(s)-1]<33?s[j]=0,f(s):*s^32||f(s+1);}
```
[Try it online!](https://tio.run/##S9ZNT07@/z/LOk0jOSOxSKtYs7qgtKRYo1jTWqs4ztiopgbM1dYGChRHZ9kWlxTlpOYBpXUNY22Mje2BYrG2BjppQBErqAYgW9tQ07r2f25iZp6GJlc1F5cCEACFS4pSSgs0lEC8yNRiHYXgzCJFEEdBSVPTGosiBQWf1BL1YoX0fCDKScvMS8eu1iM1Jycfq0x4flFOCk7T0UAiwi21/wE "C (gcc) – Try It Online")
# [C (gcc)](https://gcc.gnu.org/), ~~107~~ ~~102~~ ~~101~~ ~~100~~ 99 bytes
Saved 2 bytes thanks to @Jonathan Frech using spaces and ~
```
i,j,k;f(char*s){for(i=~++k,puts(s);i^k;k=s[j=strlen(s)-1]<33?s[j]=0,puts(s):0)*s^32?i=0:puts(++s);}
```
[Try it online!](https://tio.run/##dY4xD4IwEIV3fkVlsaUlQdnAhtXBzcEYAwmBgqUVSAsTwb9ei4kxMfhyy/vu3csVfl0UxnDSEBFXsLjnytNoqjoFOX1iLEg/DhpqFPNMxILqW0P1oCRrLfN36SEME8tSGnyCUYA8nYX7hNMgejOM7flsHjlvIXImxwFWFbQ15dhDd3FXpgk4c7VZDHARildCAJzYsNWg7uzIirf1evbIpOxWN5dOyfJv@4/y7y@zeQE "C (gcc) – Try It Online")
[Answer]
# JavaScript (ES6) 92
@Upvoters: have a look at the other JS answer down below that is **76** bytes long
```
(s,q,l=2,p=0)=>{for(alert(s);l--;p=!p)s[+p&&s.length-p]<'!'&&alert(s=s.slice(!p,-p||q,l=2))}
```
A loop looking for a space at front or at end. If found, remove space and output string. If no space found 2 times, stop.
```
F=
(s,q,l=2,p=0)=>{for(alert(s);l--;p=!p)s[+p&&s.length-p]<'!'&&alert(s=s.slice(!p,-p||q,l=2))}
// some trick to show dots instead of spaces, for test
alert=x=>console.log(x
  .replace(/^ +/g,z=>'.'.repeat(z.length))
  .replace(/ +$/g,z=>'.'.repeat(z.length))
)
function go() {F(I.value.replace(/\./g,' '))}
go()
```
```
<input ID=I value='....yes Sir!....'> (use dot instead of space)
<button onclick='go()'>Go</button>
```
[Answer]
# Perl 5, 32 bytes
*Saved 4 bytes due to [@Abigail](https://codegolf.stackexchange.com/posts/comments/351789?noredirect=1).*
```
1while s/^ /!say/e+s/ $/!say/e
```
Requires `-pl` counted as 2, invoked with `-E`. 
**Sample Usage**
```
$ echo '   test   ' | perl -plE'1while s/^ /!say/e+s/ $/!say/e'
   test   
  test   
  test  
 test  
 test 
test 
test
```
[Try it online!](https://tio.run/##S0oszvhfkFqUo6BbkOOq/t@wPCMzJ1WhWD9OQV@xOLFSP1W7WF9BBcr@r/5fAQgiU4t1FIIzixRBHC4FMPBJLVEvVkjPB6KctMy8dJCMR2pOTj6QDs8vykmBqkMDiWASAA "Bash – Try It Online")
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), ~~192~~ ~~183~~ ~~182~~ ~~181~~ ~~179~~ 178 bytes
-3 bytes thanks to Kevin Cruijssen
```
n=>{var o=n+"\n";for(var e=1;n.Trim()!=n;){if(1>(e^=1))if(n[0]<33)n=n.Remove(0,1);else continue;else if(n.TrimEnd()!=n)n=n.Remove(n.Length-1);else continue;o+=n+"\n";};return o;}
```
[Try it online!](https://tio.run/##jY89a8MwEIZ3/4qrJ4kkJiajIi@l7ZJQaAsd0gSMfLYF9gkk2TQY/3ZXcSgEOjS33NfzHvcqt1LG4qSa3Dn4jobI@dxrBb3RBexzTcCct5qqwxFyWzkeEAjxfnYe2@S5I7W9Aku45gxKkBPJbOhzC0bSIv6iWJTGsssAZSoo@bC6ZfxBkuCDLlmaMTzJlPNQ02F93G42nCQlb9iaHtl6mXKBjUNQhrymDq/dhZ5PPVExX7sVUbJDqny9@qM1i9@nRmHRd5bAiHESt8YeDTnTYPJptcedJmQli8P6xTRlMBmqmPP/Fa81uFr7e/H9OXxZBGMOGkPVXRqYY0bHaJx@AA "C# (.NET Core) – Try It Online")
[Answer]
# Java 8, ~~150~~ ~~146~~ ~~145~~ 137 bytes
```
s->{String r=s;for(int f=0;s!=s.trim();f^=1)r+="\n"+(s=f+s.charAt(0)<33|!s.endsWith(" ")?s.substring(1):s.replaceAll(" $",""));return r;}
```
-4 bytes thanks to *@Nevay* changing `(f<1&s.charAt(0)<33)` to `f+s.charAt(0)<33`.  
-1 byte by using the `!s.trim().equals(s)` trick from [*@someone*'s C# .NET answer](https://codegolf.stackexchange.com/a/143380/52210) instead of `s.matches(" .*|.* ")`.  
-8 bytes thanks to *@Nevay* again by changing `!s.trim().equals(s)` to `s!=s.trim()`, because [`String#trim`](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#trim()) will return "*A copy of this string with leading and trailing white space removed, or **this string if it has no leading or trailing white space***", thus the reference stays the same and `!=` can be used to check if they are the same reference, instead of `.equals` to check the same value.
**Explanation:**
[Try it here](https://tio.run/##rZBNSwMxEIbv/RXTIJjQNrR4c43SmwftpUIRPyDNZtvUNFky2YLU/e1rtiwiQk/rHEImM/PkfWcnD3LiS@12@UejrESER2nccQBgXNShkErDok0BljEYtwFFuwuyLL3Xg3RglNEoWIADAQ1Obo9dTxCYFT7QBINCTDMcCuSptKcsK97FjIWRIK@OjCiKYoRcbWWYRzplN1dXX0Pk2uW4MnFLCRB2hxyrNZ7IdMaukQdd2qRwbm1quCBjQhjLgo5VcBCyuslacWW1tklcp/HgTQ775LGz8fIGknUGPzHqPfdV5GUqReuo4yqR21A@1xtvi1PSfnNu5HzlB/ascQxLE4b/AQN40PESYeOh1dduvRfzXlvre6p60hh7AFY@2Lz3Wv6E/L3selA33w) (or try a more visual version [here](https://tio.run/##rZBNa8MwDIbv/RWqM1jcD9My2GFZNnrbYeulgzL2Aa7jtO5cO1hOYbT57ZlTwhiDnjIfjGVJr55XW77nY1tIs80@a6E5IjxxZQ49AGW8dDkXEuZNCLDwTpk1iLh9IE3Cf9ULF3rulYA5GEihxvHdoa1xKSa5dXEQgzydJMh23IuNxJhEbHBkg4jQJP9Ip9QNU/JmyDDGNB8iExvuZj6e0Nur62MfmTQZLpXfhD5C75FhucLTiHhKb5A5WeiAOtM6FFyQESGUJk760hlwSVUnDWVRrnSgbGH3VmWwC2ZbP6/vwGnr9Au93DFbelaElNcmNkwE5eYIm8m11fkpaMacazmf@RF7kTiChXL9/xCLokfpLxHWFhq@YKmb5oPU2nakepboOwgsrdNZ57X8Ofz3sqteVX8D) with `#` instead of spaces).
```
s->{                               // Method with String as both parameter and return-type
  String r=s;                      //  Result-String (starting at the input)
  for(int f=0;                     //  Flag-integer (starting at 0)
      s!=s.trim();                 //  Loop as long as `s` contains leading/trailing spaces
      f^=1)                        //    And XOR(1) `f` after every iteration (0->1; 1->0)
    r+="\n"                        //   Append the result with a new-line
       +(                          //    Followed by:
         s=f+                      //     If `f` is 0,
             s.charAt(0)<33        //     and `s` starts with a space
           |!s.endsWith(" ")?      //     Or doesn't end with a space
            s.substring(1)         //      Remove the first leading space
           :                       //     Else:
            s.replaceAll(" $",""));//      Remove the last trailing space
                                   //  End of loop (implicit / single-line body)
  return r;                        //  Return the result-String
}                                  // End of method
```
[Answer]
# C, ~~91~~ 90 bytes
```
i,l;f(char*s){for(i=puts(s);i;i=(s[l=strlen(s)-1]*=s[l]>32)?i:puts(s))i=*s<33&&puts(++s);}
```
[Try it online!](https://tio.run/##dY4/D4IwEMV3PkVlwJY/g7JZq6uDm4MxhoEUipfUlrRlInz2WoyJicGXW97v3r0cLzrOvYdcUoH5ozapJaPQBgPrB2exJRQoMGzvkllnZKsCKjZVygKpDuWWHGH3SRJgqd2XZZK8QZaF48mDcuhZg8IkGiMUJHAoaoYex7O7tTZHFzCr2aCYELoQQujcurVFnQ4jBahuOXtqpdSLm6s2svnb/qP6@8vkXw)
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 16 bytes
```
Ḋ=⁶Ḣ$¡UµÐĿ¹Ṛƭ€QY
```
[Try it online!](https://tio.run/##y0rNyan8///hji7bR43bHu5YpHJoYeihrYcnHNl/aOfDnbOOrX3UtCYw8v///wpgkAFUn69Qnl@UkwLkAQA "Jelly – Try It Online")
-2 bytes thanks to Erik the Outgolfer  
-1 byte thanks to miles
# Explanation
```
Ḋ=⁶Ḣ$¡UµÐĿ¹Ṛƭ€QY  Main link
       µÐĿ        While the results are unique (collecting intermediate results), apply the last link (`µ` creates a new monadic link):
Ḋ=⁶Ḣ$¡            Remove a space from the beginning if there is one
 =⁶Ḣ$             If the first character is a space, then 1, else 0
 =                Compare each character to
  ⁶               ' '
   Ḣ              Get the first comparison
Ḋ                 Then Dequeue the string (s -> s[1:])
    ¡             That many times
     U            And reverse the string (the next time this is called, it will remove spaces from the end instead)
             €    For each string
            ƭ     Alternate between two commands:
          ¹       Identity (do nothing), and
           Ṛ      Reverse
          ¹Ṛƭ€    Correct all strings that are reversed to remove the trailing space
              Q   Remove duplicates (where there was no space to remove)
               Y  Join on newlines
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 63 bytes
```
->s{*x=s;(s=~/^ /&&x<<s=$';s=~/ $/&&x<<s=$`)while s=~/^ | $/;x}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1664WqvCtthao9i2Tj9OQV9NrcLGpthWRd0aJKCgAhdI0CzPyMxJVYCoqwHKWFfU/i8oLSlWSItWVwCB5PyU1PT8nDQFCFCP/Q8A "Ruby – Try It Online")
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), ~~161 147~~ 146 bytes
```
x->{for(int l=0,r=x.length(),k=-1,u,v;((u=32-x.charAt(l)>>k)*(v=32-x.charAt(r-1)>>-1))<1;x+="\n"+x.substring(l-=k&~u|v,r+=(k=~k)&~v|u));return x;}
```
[Try it online!](https://tio.run/##fZBNTwIxEIbv/oqRA9vKbiN6XErizYPigRhj1ENZylK2tJt2ulmi8NexfKghIU6aJvPOR9@nC9GIzNbSLKbVtg4TrQootPAeHoUy8HlxATE8CoyFmTJCwyKOsIBKs1kwBSpr2LMRbvVUSyfQusEYnTLlEEbAt202/JxZR5RB0Pw6dbxlWpoS54SmFc/6aUibnJDAb2@ylhVz4e6QaDocVvSKNCeqy/pRjxcd9PO2xzvvptNrmQ8Tv3@R6IxX3U34alLX46Tim4p2N81XoDR3EoMz0Obr7Q4oP3AdgY94jVVTWEZscgA9cLx9gHClp/Ev4BgoPZIOi/EqfQpj5S53CevQ/EwPYw8SEw@ljUfH1eXZ1nuptT1XeLFOT3/k9dG4U41AeeJ8333wDCd2xyuPcslsQBbnDGpDRkzUtV4Rz5ystSgkSViSQgIJpX8S7CQWpfy/Xb/O1ttv "Java (OpenJDK 8) – Try It Online")
-1 byte thanks to *@Kevin Cruijssen*!
```
x -> {
    /*
     * l: left index (inclusive)
     * r: right index (exclusive)
     * k: side to remove from, -1:=left, 0:=right
     * u: left character   0:=space, <0:=no space (-1 if k is left side)
     * v: right character  0:=space, -1:=no space
     */
    for (int l = 0, r = x.length(), k = -1, u, v;
            ((u = 32 - x.charAt(l) >> k)
           * (v = 32 - x.charAt(r - 1) >> -1)) < 1; // loop while left or right has space(s)
            x += "\n" + x.substring(                // append newline and substring
                    l -= k & ~u | v,                // inc. left  if k is left side
                                                    //               and left has space
                                                    //            or right has no space
                    r += (k = ~k) & ~v | u));       // dec. right if k is right side
                                                    //               and right has space
                                                    //            or left has no space
    return x;
}
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~25~~ 17 bytes
*-8 bytes by borrowing the [no-need-for-an-end-check idea from Emigna](https://codegolf.stackexchange.com/a/143382/73296)*
```
,v2F¬ðQi¦DNiR},}R
```
[Try it online!](https://tio.run/##MzBNTDJM/f9fp8zI7dCawxsCMw8tc/HLDKrVqQ36/18BG0gEkwA "05AB1E – Try It Online")
I'm pretty sure a less straightforward approach can beat that solution easily. For now...
**Explanations:**
```
,v2F¬ðQi¦DNiR},}R           Full Programm
,                           Print the input string
 v                          For each char of the string
                               (we don't really care, we only need to loop
                                enough times to accomplish our task, since
                                we print conditionally we can loop more
                                times than necessary)
  2F...........}            Two times...
    ¬õQi                       Is 1st item a space?
        ¦D                        Remove 1st item + duplicate
          NiR}                    If on the second pass: reverse the list
              ,                   Pop & print with newline
               }               End If
                 R          Reverse the list
```
[Answer]
# [R](https://www.r-project.org/), ~~145~~ ~~133~~ 111 bytes
*-12 bytes thanks to @Giuseppe, by storing the result of `sub` in a new variable and testing for whether it has changed*
*-22 bytes by returning a vector of strings rather than a string with newlines*
```
function(s){L=s
while(grepl("^ | $",s)){if((x=sub("^ ","",s))!=s)L=c(L,x)
if((s=sub(" $","",x))!=x)L=c(L,s)}
L}
```
[Try it online!](https://tio.run/##LcsxDoMwDAXQPacIFoMt5Qq@QTYmlg5FSYmEKIqLGoly9jQu/Zu/3881co37Or3Sc0Whw7OY95yWgI8ctgXhZj@2BydER4qIhWW/awsOfm3HQp4n9K6QUSGX0FETRUX5C6HT@LPG9m0Zgzg7pNzpYYHqFw "R – Try It Online")
Explanation on a partially ungolfed version: 
```
function(s){
  L=s                          # Initialise a vector with the original string
  while(grepl("^ | $",s)){     # While there are leading or trailing spaces...
    if((x=sub("^ ","",s))!=s){ # Check whether we can remove a leading space
      L=c(L,x)                 # If so, add the shortened string to the vector
    }
    if((s=sub(" $","",x))!=x){ # Check whether we can remove a trailing space
      L=c(L,x)                 # If so, add the shortened string to the vector
    }
  }
  L                            # Return the vector
}                              
```
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), ~~137~~ ~~125~~ ~~121~~ ~~120~~ 124 bytes
```
s->{int i=1;do System.out.println(s);while(s!=(s=s.substring(s.charAt(0)<33?i:(i=0),s.length()-(s.endsWith(" ")?i^=1:0))));}
```
[Try it online!](https://tio.run/##TY7BasMwEER/RfVJKrVwyC2KEko/IYcQSguqJNvryJLwrlOKybe7Ir10bjO8GWYwN1On7OPgriuMOU3EhpLJmSDIdo6WIEX5rCCSn1pjPbssbyniPPppf6IJYndgmWm2Yn1YCsVAb5RL7PSD5EeZZpK5UBQiR6G@ewie45PmqFHi/IWPCY7S9mZ6Jd6I/XZ7hB0H3YgXlMHHjnou6oL46PAMxVWsEkf41JtdI4rUfVVIhsCyWwLHRgOR/317/zBiydJY6zOV3j/Z5HyXQvswVRm5r78 "Java (OpenJDK 8) – Try It Online")
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~21~~ 16 bytes
```
tnE:"t@o&)w46-?x
```
This uses dots instead of spaces for greater clarity. For spaces replace `46` by `32`.
[**Try it online!**](https://tio.run/##y00syfn/vyTP1UqpxCFfTbPcxEzXvuL/f3U9bCARTKoDAA)
### Explanation
```
tn      % Input (implicit). Duplicate and push length, say L
E       % Multiply by 2
:       % Push range [1 2 ... 2*L]
"       % For each k in that array
  t     %   Duplicate the string at the top of the stack
  @     %   Push k
  o     %   Parity: gives 1 or 0
  &)    %   Two-ouput indexing. Pushes the k-th entry of the string and then
        %   the rest of the string. The 1-st output is the first, the 0-th
        %   is the last (indexing is 1-based dand modular)
  w     %   Swap
  46-   %   Subtract 46, which ias ACII for '.'
  ?     %   If non-zero
    x   %     Delete sub-string that was obained by removing that entry
        %   End (implicit)
        % End (implicit)
        % Display stack (implicit)
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), ~~23~~ 22 bytes
```
u§↑L`G`I¢e₁ȯ↔₁↔
?tI<"!
```
Thanks to Leo for -1 byte.
[Try it online!](https://tio.run/##NYwxDsIwDEX3nuI3c8UBEBIjVGJjYmtUuTSipFXsssPQHYkTsDByh06coxcJIYCH5y/5fdc9H7zvx8c0XDfFqsjHO02X8@s5DbewA5Ol5AuVeoT5RmBNTUcOVW9LMa2dw9GxPRGMNWJ0A@50SbMkVoBYySs0xAyptQ0gsDhj91CpyqIIify/qoxjQVlrp0sh93OQR1LDFETpnYVmGJ55rz6HHXGGrXFp1NQb "Husk – Try It Online")
## Explanation
The function ``G`I` should really be a built-in...
```
?tI<"!  Helper function: remove initial space.
?  <"!  If less than the string "!",
 t      remove first character,
  I     else return as is.
u§↑L`G`I¢e₁ȯ↔₁↔  Main function.
         e       List containing
          ₁      the helper function
           ȯ↔₁↔  and the composition reverse-helper-reverse.
        ¢        Repeat it cyclically.
    `G`I         Cumulative reduce from left by function application
                 using input string as initial value.
 §↑L             Take first length(input) values.
u                Remove duplicates.
```
[Answer]
## C++, ~~196~~ ~~193~~ ~~189~~ ~~186~~ 183 bytes
-10 bytes thanks to Jonathan Frech   
-3 bytes thanks to Zacharý
```
#include<iostream>
#include<string>
#define D std::cout<<s<<'\n'
#define R ~-s.size()
auto u=[](auto s){D;while(s[0]<33||s[R]<33){if(s[0]<33)s.erase(0,1),D;if(s[R]<33)s.erase(R),D;}};
```
Compilation with MSVC requires the un-activation of SDL checks
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), 176 170 bytes
```
using System;s=>{Action o=()=>Console.WriteLine(s);o();Func<int>l=()=>s.Length-1;while(s!=s.Trim()){if(s[0]<33){s=s.Remove(0,1);o();}if(s[l()]<33){s=s.Remove(l());o();}}}
```
[*Try it online!*](https://tio.run/##bZDLasNADEX3/golm85AYhKy9ANKoXThbppCKCELMx47gvEIRpO0xfjbXT9KwU20Ebr36IEUrxU53V0YbQX7b/a6jgJlcmb4CpqAfe5RwZWwgNccLQj2rkePJ8hdxbJHoI9H5ZFsPHkplJB0nKTNJAMlQibpE1kmo8ODQ68ztFqwjEjI6PliVYzWp2bkOMy0rfx5vY0@z2h6bJFw@O6wFlI2WAo@bk7xbicb7vU3XdNVi81qOw1rR8AIeYP02i/Stl00nl2K5ZBAUaErMuVYLOXM/NC8gj26xT0TINP@gaEiGPqHH86YF20MzZQDOVPcTPkX@d@uNmi7Hw)
This is an alternative to [@someone's answer](https://codegolf.stackexchange.com/a/143380/61283 "@someone's answer"), and just outputs the strings directly.
[Answer]
# JavaScript (ES6), 76 bytes
```
f=(s,r,n,l=s.length)=>s[r?--l:0]<"!"?s+`
`+f(s.slice(!r,l),!r):n?s:f(s,!r,1)
```
Outputs as a multiline string.
## Test Cases
Using dots instead of spaces, as most answers are doing.
```
f=(s,r,n,l=s.length)=>s[r?--l:0]<"!"?s+`
`+f(s.slice(!r,l),!r):n?s:f(s,!r,1)
// converting to and from dots and spaces
let dots=s=>s.replace(/^\.+|\.+$/gm,x=>" ".repeat(x.length));
let spaces=s=>s.replace(/^ +| +$/gm,x=>".".repeat(x.length));
["....Yes, Sir!.....", "......Let's go golfing...", "Hello..", "World", ".....................a....."]
.forEach(test=>O.innerHTML+=spaces( f(dots(test)) ) + "\n\n");
```
```
<pre id=O></pre>
```
[Answer]
## Sed, 24 bytes
```
p;:s s/ //p;s/ $//p;ts;D
```
[Try It Online !](https://tio.run/##K05N0U3PK/3/v8DaqlihWF9BX7/AGkipgOiSYmuX//8VFEpSi0sUFAA)
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~88~~ 83 bytes
*5 bytes off thanks to [Stewie Griffin!](https://codegolf.stackexchange.com/users/31516/stewie-griffin)*
```
x=[input('') 0];for p=mod(1:sum(x),2)if x(~p+end*p)<33,disp(x=x(2-p:end-p)),end,end
```
[**Try it online!**](https://tio.run/##y08uSSxL/f@/wjY6M6@gtERDXV1TwSDWOi2/SKHANjc/RcPQqrg0V6NCU8dIMzNNoUKjrkA7NS9Fq0DTxthYJyWzuECjwrZCw0i3wAoorFugqakDpEH4/38lBRBIzk9JTc/PSQNzlAA)
[Answer]
# x86 machine code for Linux, 60 bytes
```
e8 1f 00 00 00 31 c0 80 3f 20 75 09 47 4d 74 10
e8 0f 00 00 00 80 7c 2f ff 20 74 05 84 c0 75 e5
c3 4d eb dc 6a 04 58 50 31 db 43 89 f9 89 ea cd
80 58 6a 0a 89 e1 89 da cd 80 58 c3
```
This is a function for Linux x86. It takes as input pointer to the string in `edi` and string length in `ebp`.
Ungolfed, with some infrastructure to test (compile with FASM, run with the string as program argument; look for `undress:` label for actual function code):
```
format ELF executable
segment executable
SYS_WRITE = 4
    jmp     callUndress
; -------------------- the function itself --------------------------------
; Input:
;   edi=string
;   ebp=length
undress:
undressLoopPrint:
    call    print
undressLoop:
    xor     eax, eax    ; flag of having printed anything on this iteration
    cmp     byte [edi], ' '
    jne     startsWithoutSpace
    inc     edi
    dec     ebp
    jz      quit
    call    print
startsWithoutSpace:
    cmp     byte [edi+ebp-1], ' '
    je      endsWithSpace
    test    al, al      ; if print has been called, then we have 0x0a in eax
    jnz     undressLoop
quit:
    ret
endsWithSpace:
    dec     ebp
    jmp     undressLoopPrint
print:
    push    SYS_WRITE
    pop     eax
    push    eax
    xor     ebx, ebx
    inc     ebx ; STDOUT
    mov     ecx, edi
    mov     edx, ebp
    int     0x80
    pop     eax
    push    0x0a    ; will print newline
    mov     ecx, esp
    mov     edx, ebx ; STDOUT=1, which coincides with the length of newline
    int     0x80
    pop     eax
    ret
; --------------------- end undress ---------------------------------------
SYS_EXIT = 1
STDERR = 2
callUndress:
    pop     eax     ; argc
    cmp     eax, 2
    jne     badArgc
    pop     eax     ; argv[0]
    pop     edi
    mov     al, 0
    cld
    mov     ecx, -1
    repne   scasb
    lea     edi, [edi+ecx+1] ; argv[1]
    neg     ecx
    sub     ecx, 2
    mov     ebp, ecx     ; strlen(argv[1])
    call    undress
    xor     ebx, ebx
exit:
    mov     eax, SYS_EXIT
    int     0x80
    ud2
badArgc:
    mov     esi, eax
    mov     eax, SYS_WRITE
    mov     ebx, STDERR
    mov     ecx, badArgcMsg
    mov     edx, badArgcMsgLen
    int     0x80
    mov     ebx, esi
    neg     ebx
    jmp     exit
badArgcMsg:
    db      "Usage: undress YourString",0x0a,0
badArgcMsgLen = $-badArgcMsg
segment readable writable
string:
    db      100 dup(0)
    stringLen = $-string
```
[Answer]
# [PHP](https://php.net/), 117 bytes
I add an extra space at the start so it will take the space out and show the original without any extra code.
Kinda new to this... would the <?php and the space at the start of the PHP file add 6 extra bytes or do I get that for free?
```
$s=" $argn";while($r!=$s){$r=$s;if($s[0]==" ")echo($s=substr($s,1))."
";if($s[-1]==" ")echo($s=substr($s,0,-1))."
";}
```
[Try it online!](https://tio.run/##dcrBCsIwDAbge5@ilh5WWGXT4yzefAnxMGddB6UpTWUH8dWtKejRQP7khy@6WA7HSCnRCC7HNAcxrG7xtpFpYySqp0x0huXeSDx3F0NMKDs5oG7wccWc6Gt7pbaCia/T/V/YtfpnX6XwOs56D3yF5G/UGG22mHes5r4CFoBPbgyzfUPMCwQs@vQB "PHP – Try It Online")
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 28 bytes
```
QW<lrKQ6lQ=hZ?&%Z2qdhQ=tQ=PQ
```
**[Try it here!](https://pyth.herokuapp.com/?code=QW%3ClrKQ6lQ%3DhZ%3F%26%25Z2qdhQ%3DtQ%3DPQ&input=%22+++++codegolf+++++%22&test_suite_input=%22+++++codegolf+++++%22%0A%22world%22%0A%22++++Yes%2C+Sir%21+++++%22%0A%22Hello++%22&debug=0)** or **[Verify all test cases!](https://pyth.herokuapp.com/?code=QW%3ClrKQ6lQ%3DhZ%3F%26%25Z2qdhQ%3DtQ%3DPQ&input=%22+++++codegolf+++++%22&test_suite=1&test_suite_input=%22+++++codegolf+++++%22%0A%22world%22%0A%22++++Yes%2C+Sir%21+++++%22%0A%22Hello++%22&debug=0)**
# Explanation
```
QW<lrKQ6lQ=hZ?&%Z2qdhQ=tQ=PQ   ~ Full program. Q is autoinitialized to input.
Q                              ~ Output the input.
 W<lrKQ6lQ                     ~ Loop while the condition is met.
  <                            ~ Is smaller?
   lrKQ6                       ~ The length of the original input, stripped on both sides.
        lQ                     ~ The length of the current Q.
          =hZ                  ~ Increment a variable Z, initially 0
             ?&%Z2qdhQ         ~ If Z % 2 == 1 and Q[0] == " ", then:
                      =tQ      ~ Make Q equal to Q[1:] and output, else:
                         =PQ   ~ Make Q equal to Q[:-1] and output.
```
[Answer]
# [Python 2](https://docs.python.org/2/), 79 bytes
-1 byte thanks to @JonathanFrech
```
f=lambda s,i=1:[s]+(s>i*'!'and'!'>s[-1]and f(s[:-1])or'!'>s and f(s[1:],0)or[])
```
[Try it online!](https://tio.run/##fYwxT8QwDIXn9le4U9qjRBxjpd52iAGJARZUVSi0ac9SSCInp@N@fXEqVbcgPNjPz9@zv8aTs4/LMrVGfX@NCkKN7b7pQn9XhgPuRCGUHbkfQne/71nDVIauYV05Wn3YzH3T1w/sdn21RLo2eXY5odHwTmfNS4bQAqnLJ1p/jmUlSXujBl0KKWoQICpmJkfgAC0/xCqFMk9oI7gbDYmWK61C0MRHaFtAGSKhL5O/ZnL9M2gf4fj6dCRyxN88Bxb5V6m150nkaUkqX2eRNNfgRj07M22glB861PCGVNwsKV90FAFmB4lFO/9/edbGuG3@Ag "Python 2 – Try It Online")
The test suit replaces `"."` with `" "` before calling the function and replaces `" "` back to `"."` before printing the results for clarity.
[Answer]
# C# - yet again, 125 bytes
```
while(s.Trim()!=s){if(s[0]==' '){yield return s=s.Substring(1);}if(s.Last()==' '){yield return s=s.Substring(0,s.Length-1);}}
```
Cheers!
[Try it online!](https://tio.run/##hVDRasIwFH3vV9z5YoIzuOeuexEZgttgDvYw9hDTVANp6nJTNyn9dpdYq3YKO5Byc3vPuTlH4FCg2JWozBLmW3Qyj6PzG5sp8xVHQnNE@IEqiuCAtVUb7iSg406JdnxcaC2FU4VB9iiNtEqw6cSUubR8oeU9OuvFHyAjTQVIj4rV7nultCTI3qzKCb1JkFbKT36MPpOkD31abZXUKVjpSmsAE2TzctEIkTsa12GYzTg6Qv8njG79rDRLtxoGbr2rT97KhfaeDtY2hUrhiStDzt56rAJaL3Gnu3cD5Kb5y6b4XGr9Yif52m0JQgJjn1KhJXuVPPU5S0Ip7Sh0twRkhZVcrIBsuIUClAlJ/mFdZwa0C9@tcnK/sTfswcALDcBXNL5g1VH3Fl2TO72/K9DEHqI9JRU@UVvsEeHFVt/gmGbhHGg8axpZCr8 "C# (Visual C# Compiler) – Try It Online")
[Answer]
# [Octave](https://www.gnu.org/software/octave/), 89 bytes
```
s=input('');while any(s([1,end])<33)if s(1)<33,s(1)=[],end,if s(end)<33,s(end)=[],end,end
```
[Try it online!](https://tio.run/##y08uSSxL/f@/2DYzr6C0RENdXdO6PCMzJ1UhMa9So1gj2lAnNS8lVtPG2FgzM02hWMMQxNQB0bbRsSA5HbAwkAGVALFgUkD8/7@SAgz4pJaoFyuk5wNRTlpmXjpQSAkA "Octave – Try It Online")
I'll add an explanation later, when I have the time. I might be able to golf off some bytes if I change the approach completely, but I can't see how unfortunately.
The last letters here spell out: "sendsendendend". I wish there was a way to store `end` as a variable and use that, but guess what ...
[Answer]
# Bash, ~~98~~ 94 bytes
Saved 4 bytes using subshell instead of sequences (poor performances)
```
r()(s=$1;[[ $s = $b ]]||([[ $s = $a ]]||echo "$s"
b=$a a=$s;((i=!i))&&r "${s# }"||r "${s% }"))
```
First answer
```
r(){ s=$1;[[ $s = $b ]]||{ [[ $s = $a ]]||echo "$s"
b=$a a=$s;((i=!i))&&r "${s# }"||r "${s% }";};}
```
Note the `!` must be escaped in interactive mode
]