[Question]
  [
I've been playing around with a robot on the coordinate plane. This robot is able to tell me if it goes left, right, up, or down by reporting back a string consisting of the letters `L`, `R`, `U`, and `D`, such as `DLURRDLURDLLLRRLRLDURRU`. Each character represents a movement of one unit. However, it seems that the robot is going in loops on the plane, returning to coordinates that it has already visited. I don't want the robot to do that. I'd like the robot to tell me about the path it takes without any loops included - these loops should be removed from left to right in the string. Every step in the string it reports should represent movement to a cell that it has not yet visited before. If the robot ends where it starts, then it should report back an empty string. 
```
Test cases
ULRURU -> UURU
URDLDRU -> DRU
LLLLRRRL -> LL
LLLULRRRL -> LLLUR
UURDDRULDL -> {empty string}
DLURRDLURDLLLRRLRLDURRU -> R
URULLLDLUULDDLDRDDLLLLLDLLUUULLURU -> URULLLDLUULDDLDRDDLLLLLDLLUUULLURU
```
This is a standard code golf challenge, where the shortest answer wins. Standard rules apply.
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 20 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
O2ȷ:ı*S
ẆÇÐḟḢ⁸œṣFµÐL
```
**[Try it online!](https://tio.run/##y0rNyan8/9/f6MR2qyMbtYK5Hu5qO9x@eMLDHfMf7lj0qHHH0ckPdy52O7T18ASf////u/iEBgWBCBcfH5@gIJ8gHxegQCgA "Jelly – Try It Online")** Or see the [test-suite](https://tio.run/##y0rNyan8/9/f6MR2qyMbtYK5Hu5qO9x@eMLDHfMf7lj0qHHH0ckPdy52O7T18ASf/4fbHzWtifz/P1o91CcoNChUnUtHPTTIxccFwvQBgqCgIB8oOxTOCQUqAqrxcQHzXHxCg4JAhAtYvU@QjwtQAGpYKFAMKAdUCzLWBaQEJAAUAcqArYwFAA "Jelly – Try It Online").
### How?
```
O2ȷ:ı*S - Link 1, distance travelled: list of UDLR characters
O       - ordinals -> U:85 D:68 L:76 R:82
 2ȷ     - 2000
   :    - integer division -> U:23 D:29 L:26 R:24 (Note mod 4 these are 3 1 2 0)
    ı   - square root of -1  - i.e. (0+1j)
     *  - exponentiate -> U:(0-1j) D:(0+1j) L:(-1+0j) R:(1+0j)
      S - sum - 0 iff the path is a loop
ẆÇÐḟḢ⁸œṣFµÐL - Main Link: list of UDLR characters
         µÐL - loop until no change occurs:
Ẇ            -   all sublists
  Ðḟ         -   filter discard those which are truthy (non-zero) under:
 Ç           -     call last Link (1) as a monad
    Ḣ        -   head - X = first, shortest loop (if none this yields 0)
     ⁸       -   chain's left argument
      œṣ     -   split at sublists equal to X
        F    -   flatten
```
[Answer]
# [J](http://jsoftware.com/), 51 39 bytes
```
([,~i.~{.])/@|.&.([:+/\0,0j1^'ULDR'&i.)
```
[Try it online!](https://tio.run/##hY6xCsJADIZ3nyI49Fq8pnU9KAgGp0yBm6ouYrFdfAClr34mom2dPLgj93/5/2RIa3QdNAEceKgh6C0R9sKHlLd@7HF84Kmodk/MMG/DpjrWvh62ZxeZxGU9FqlYXS@3O7gYJTooA3Ras9jvQ2gBhJhmwvwFrEdEeCYcZQHjD53iNE/jmCainsYIqV3soXcwC5MK02DdTnXl6rWNyNpMUCXa6MXGfzvTCw "J – Try It Online")
*-12 bytes thanks to Bubbler! For the idea of combining "Under"s into a single train, and skipping an unnecessary increment of the indexes*
## The idea
1. Convert the letters to their indexes within the `ULDR`
2. Convert those indexes to complex vectors: Think `U = i`, `L = -1`, `D = -i` `R = 1`
In fact, because of rotational symmetry, we don't actually care which direction is "up" as long the relative order of the directions is preserved.
3. Scan sum those vectors to get the path positions (still as complex numbers)
4. Reduce the path into a loop free version: Any time we arrive at a point we've seen, remove all history up to and including that old point.
5. Invert steps 1 to 3, in reverse order.
The fun thing is that step 5 is accomplished with J's [Under](https://code.jsoftware.com/wiki/Vocabulary/ampdot) conjunction, which allows you to perform a transformation, do stuff, and then have the inverse transformation automatically applied. Here, J is smart enough to know how to invert the entire train comprising steps 1 through 3 in reverse order: 
```
                             Elementwise
reduce to       Scan sum     index within 
remove loops    of...        'ULDR'
     |             |             |
vvvvvvvvvvvvv     vvvvv      vvvvvvvv
([,~i.~{.])/@|.&.([:+/\0,0j1^'ULDR'&i.)
               ^^      ^^^^^^
               |         |       
             Under     0 prepended to
                       i raised to...
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~101 ... 91~~ 90 bytes
```
f=s=>s&&[s[Buffer(s).every(c=>p+=[w=s.length,~!++i,1,-w][c%5],i=p=0)-1]]+f(s.slice(p?1:i))
```
[Try it online!](https://tio.run/##hZA/T8MwEMV3PkWIRGUrf0oGFiS3EvJ4kyVPUYbK2MEoTaw4tKoQfPVwJjDQ0OYGD0/3e/f8XneHnVe9dUPWds96HA3zbONXq9KXT2/G6J54muuD7k9EsY1LWHlkPm90Ww8v6edtkti0SLNjVaq7hyq1zLF7mhVVlRjic99YpYnbFo@W0lF1re8anTddTQyJJQgpZBxdGUqj9TqSuHZzDgsO/Do9wXzOAo4QAuIlFuAfVC6wvyhIMQuNqTEP8Mv4RL/rvRtOkR9629Yf5zYcrUV4@PdHQABH4U8Xk808AB4HPC8xQ@iPB4cgoCJDYhn/VL64OH4B "JavaScript (Node.js) – Try It Online")
## How?
### Method
For each index \$n\$ in the input string, we initialize our position to \$(0,0)\$ and run a simulation of the walk starting from the \$n\$-th character. If there's some move at \$n+i-1,i>0\$ that brings us back to \$(0,0)\$, it means that we have identified a loop: we skip the entire segment and restart at \$n+i\$.
```
   n  n+i-1
   v    v
...LLURRD...
         ^
        n+i
```
Otherwise, we append the current move to the output (***L*** in the above example) and advance to \$n+1\$.
### Implementation
* Instead of relying on an explicit counter \$n\$, we use recursive calls to our main function where the leading characters of the input string are gradually removed.
* Instead of using a pair \$(x,y)\$ to keep track of our position, we actually use a scalar value \$p=x+y\cdot w\$, where \$w\$ is the remaining number of characters in the string. This is safe because we can't have more than \$w\$ moves in the same direction from this point.
* To convert a character move into a direction, we take its ASCII code modulo \$5\$. The ASCII codes of \$(D,L,R,U)\$ are \$(68,76,82,85)\$, which are conveniently turned into \$(3,1,2,0)\$.
## Commented
```
f = s =>                   // f is a recursive function taking a string s
  s &&                     // if s is empty, stop recursion
  [                        // wrapper to turn undefined into an empty string:
    s[                     //   get either s[0] (next char.) or s[-1] (undefined):
      Buffer(s).every(c => //     for each ASCII code c in s:
        p += [             //       add to p:
          w = s.length,    //         +s.length for up ('U' -> 85 -> 85 % 5 = 0)
          ~!++i,           //         -1 for left ('L' -> 76 -> 76 % 5 = 1)
                           //         (increment i)
          1,               //         +1 for right ('R' -> 82 -> 82 % 5 = 2)
          -w               //         -s.length for down ('D' -> 68 -> 68 % 5 = 3)
        ][c % 5],          //       using c modulo 5
                           //       stop if p = 0, meaning that we're back to our
                           //       starting point
        i = p = 0          //       start with i = p = 0
      ) - 1                //     end of every(), subtract 1
    ]                      //   end of s[] lookup
  ] +                      // end of wrapper
  f(                       // recursive call with either:
    s.slice(p ? 1 : i)     //   s.slice(1) (no loop)
  )                        //   or s.slice(i) (skipping the loop)
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), 26 bytes
```
t"0J&y15\^hYs&=XR&fq&:[]w(
```
[Try it online!](https://tio.run/##y00syfn/v0TJwEut0tA0Ji4jsljNNiJILa1QzSo6tlzj/3/10KBQHx8fF5/QUB8XFx@XICDhAxYAigBlgNLqAA) Or [verify all test cases](https://tio.run/##y00syfmf8L9EycBLrdLQNCYuI7JYzTYiSC2tUM0qOrZc43@suq6ueoRLyH/1UJ@g0KBQdS710CAXHxcwywcIgoKCfCDMUBg7FKgCqMDHBcRx8QkNCgIRLmDFPkE@LkABiDmhQCGgFFAlyEQXkAqQAFAEKAOyDAA).
### Explanation
```
t        % Implicit input. Duplicate
"        % For each
  0      %   Push 0
  J      %   Push j (imaginary unit)
  &y     %   Duplicate third-topmost element from the stack: current string
  15\    %   ASCII code of each character, modulo 15. This gives 10, 7, 8, 1
         %   for 'U', 'R', 'L', 'D' respectively
  ^      %   Element-wise power. This gives j^10=-1, j^7=-j, j^8=1, j^1=j for
         %   'U', 'R', 'L', 'D'. These are the steps followed by the robot in
         %   the complex plane (rotated and reflected, but no matter)
  h      %   Concatenate. This prepends the 0, as starting point of the path
  Ys     %   Cumulative sum. This computes the path traced by the robot
  &=     %   Matrix of pair-wise equality comparisons for robot positions
  XR     %   Upper triangular part, without diagonal
  &f     %   Row and column indices of nonzeros. This will be non-empty if
         %   there is a loop in the path
  q      %   Subtract 1
  &:     %   Two-input range. This uses the first element from each input,
         %   that is, the first loop found
  []w(   %   Push [], swap, assignment index: this removes the characters that
         %   caused the loop
         %   string
         % End (implicit). The loop is run as many times as the input length,
         % which is an upper bound to the number of loops
         % Display (implicit)
```
[Answer]
# T-SQL, 236 bytes
First time I ever use `PI()` in sql
I am [using table as input](https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods/5341#5341)
```
WHILE @@rowcount>0WITH C
as(SELECT*,sum(ascii(a)/12-6+3/(ascii(a)-79)*pi())over(order
by b)x FROM @)DELETE C
FROM C,(SELECT top 1max(b)i,min(b)j
FROM C GROUP BY x HAVING SUM(1)>1or x=0ORDER BY 2)z
WHERE(i=j or j<b)and i>=b
SELECT*FROM @
```
**[Try it online](https://data.stackexchange.com/stackoverflow/query/1243748/remove-loops-from-a-walk)**
[Answer]
# [Java (JDK)](http://jdk.java.net/), 229 bytes
```
s->{var l=new java.util.Stack();int x=0,y=0,i;for(var c:(s+"").getBytes()){l.add(x+","+y);i="DLUR".indexOf(c);x+=~i%2*~-i;y+=i%2*(i-2);i=l.indexOf(x+","+y);if(i>=0){var z=l.subList(i,l.size());s.delete(i,i+z.size());z.clear();}}}
```
[Try it online!](https://tio.run/##bZBNa@MwEIbv@RXCEJBrR5Qe43UOXR@1LCj4VHpQZblMKtvBGmfjBPevu6O0TbfsCqQZPe87@pidPujVrnqZodl3PbId7cWA4MRN9g@qh9YgdO3/NI@91Q0pxmnv2S8NLTvvhycHhnnUSOHQQcUaEvgWe2ifHx51fP7ZtX5obP/jnd0P4Crbb@p89qvN@aB75vLW/vnrpi1q88LjDFpkx/w2HWlCVnc9D26z5j6Jolg8W7wf0Xoex2cndFXxYxKlUTJSZR4VslSRgLayx981N3F2TPJXWN7dvK4gG5M8pBxWd8Hsrr6vE2oOm/w2vjzwRA4/PEnwyCGlHE6Wbs28qKyzaAlCcrrikzDO6p5@ME3TnC0Yjc/X45paciGMfWsI8yxnoQ/fKMc4@3DXQhtj98j9FW1Hj7YR3YBiT0VY82jp12zpl22UYvppnBZhTot5LqUqVTmXqpAFRUlDKSVDUr5nJWkkyULOoYMqLMXFJpUsCITqkgAJ5ArnFEEPgAgpJL8B "Java (JDK) – Try It Online")
## Credits
* 5 bytes saved thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)
* 22 bytes saved thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~119 ... 111~~ 110 bytes
Outputs by modifying the input string.
```
p;f(char*s){for(char*r,*q=s;*q;p?*s++=*q++:(q=r))for(r=q,p=0;*r?p+=(*r%17?strlen(q):1)*~-(*r++%5&2):0;);*s=0;}
```
[Try it online!](https://tio.run/##hZFPa8IwGIfvfopQcOSPYlutA0PwkmNOgZy2HUpnXUFrm8jGEPfR170xKiqF9RDK73nyy5u2GK@LousaXuLiI7fUkUO5s@HdjmgrHKctb5bUMSZoy9gCt8IS4iUr2lEjYk7tsmECUztMnpdubzerGrdkkRD6M4aUsWH2lJJFzAmnDvxj97mr3tE2r2pM0GGAkD8OufjlDQkUGaWNNhG/5sk511LJO5AGoODRWqsbMr0S84hm5zaogzYlb1kWmFRGa7/IU7PSSkJwe/L8MpIBA0zo8cNJv8EHkAAJ14BNJXYx4aixVb0vcTR0r3U0QqdsMkEwiglS0iMlQZIXJ@1x0uAoFZRpjzK9KDBVsGY91ixYh9W22X8j@JdVvT4GPevRs6CfC@d3BnCETpm/4r8fanDsfotyk69dN/76Aw "C (gcc) – Try It Online")
### How?
The algorithm is the same used [in my JS answer](https://codegolf.stackexchange.com/a/205221/58563) with a few differences:
* We use a `for` loop instead of a recursive approach.
* We overwrite the input string with the output. This is safe because what is written is at most as long as what is read, and the meaningful information is always ahead of both the read and the write pointers (`q` and `s` respectively).
* Given the ASCII code `c` of the move character, we use `c % 17` to find out if it's a vertical or horizontal move, and `c % 5 & 2` to distinguish between *down* and *up* or between *left* and *right*.
```
         | 'D' (68) | 'L' (76) | 'R' (82) | 'U' (85)
---------+----------+----------+----------+----------
 % 17    |     0    |     8    |    14    |     0
 % 5 & 2 |     2    |     0    |     2    |     0
```
[Answer]
# perl -nF/(?{s-.\*(??{!($&=~y&R&&c==$&=~y&L&&c&&$&=~y&U&&c==$&=~y&D&&c)})--g;print})(\*COMMIT)/, 62 12 5 0 bytes
[Try it online!](https://tio.run/##TYxBCsIwEEX3vYUgISnErlxJ6MJBEKYIg3MCESlIG9pupNSjW3/Mxlkkj/cmiffhuV8xyqKihQox4WaMiHACzaRoSExcEKtIOui3xsIEkV4rBAK20j@UehIwKMifPk5t342r706VrefR70pb1/PGbk14v4wYcwshM4ONyax/nsBucd4/DnFou2lxtjxemuZ8ddUX "Perl 5 – Try It Online")
Finds substrings with the same amount of Ls and Rs, and the same amount of Us and Ds, and removes them. Prints the result.
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), 253 252 243 bytes
```
static String r(String s){String e=s;int l=s.length();for(int i=0;i<l;i++)for(int j=i+1;j<l;j++){int u=0;for(int k=i;k<=j;k++)u+=(9*(e.charAt(k)%6/3)+1)*2*(5.5-(e.charAt(k)-12)/11);if(u==0)return r(e.replace(e.substring(i,j+1),""));}return e;}
```
[Try it online!](https://tio.run/##hZDBa8IwFMbP@lcUYZC0Wq3DwYg5DHrMLpGexg6xRk1a05KkwpD@7d2r1LHL1hzC4/d9eS/f0@IqFlUtjT4UXV4K54J3oUxwm04754VXebDzVplTYNFQOHwbKkkdUcYHJXVxKc3JnxEmx8qiHiq6ImpbEhVF@ME0VVFCNFAN9NajBmwPuaCKFFuqSQFqE1H0GiIZ52dh3zwq8NPL8hlHCQ7XIdrEm8VvbZGs8TJJMFFH1FC6wlb6xhr4tYytrEuRS6hcs3f3ryM119BpPpthTNrBK0nbTepmX0LoIfu1UofgAgsZwn98BsKeHIb9TCa7L@flJa4aH9cg@tIgi2YZ4xnP@r5/W3jK0hEPg8M5Z2OmbNyVwTwYx9L/bSnLOO@v9D6acZYCGEuSgRkeQfc@U9q/7QEQUH4W0U7b7hs "Java (OpenJDK 8) – Try It Online")
This uses a recursion method, so I'm not entirely sure if it's being scored correctly.
It has a limit of going off 9 tiles in a given loop, but that can be increased to any amount as needed. 
Ungolfed:
```
public static String remove(String str) {
    String removed = str;
    int l = str.length();
    for (int i = 0; i < l - 1; i++) //-1 optional
        for (int j = i + 1; j < l; j++) {
            int upDownLeftRight = 0;
            for (int k = i; k <= j; k++)
                upDownLeftRight +=(9*(e.charAt(k)%6/3)+1)*2*(5.5-(e.charAt(k)-12)/11);
            if (upDownLeftRight == 0)
                return remove(removed.replace(removed.substring(i, j + 1), ""));
        }
    return removed;
}
```
A few seconds before I was going to submit this the post closed, a few days ago. Just realized it was opened back up.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~94~~ 93 bytes
*-1 byte thanks to @dingledooper!*
```
r=""
x,=l=[0]
for c in input():x+=1j**(ord(c)%15);r+=c;l[len(r):]=x,;r=r[:l.index(x)]
print r
```
[Try it online!](https://tio.run/##hU/BasQgEL3PV0igrO5mQ7fQS4J78uhJ8BT2sE0stRgjaiH79emYtNBbRRze8715M@GRP2b/sg7zaAgnVVWtkVcVLDV3vH@@wfscyUCsxxu@MmXtcuKXz@ORznGkA3u6vLIunvjQud4ZTyNrb3ypu8hj37rG@tEsdGE3CNH6TOKKCQB2CnPMJD3S1t9Zb0oE4ibl0foWSKqJWYIZshlxrukeaMoRf6MN9WZoUnA208P5emAM9vFQ6e7T23hvE6DdDKTsBWQP/@33g3FVLZVWmpyvRGMFrYQUO8YCEo9SShYsZYH6D5ZaAboEKqXYOBDIqfKIzSmVFEhs/VCLOolKjfISI4qoEMjo0m2f41/VNw "Python 2 – Try It Online")
A minor improvement over [@xnor's solution](https://codegolf.stackexchange.com/a/205285/92237) using slice assignment. Be sure to check out and upvote his answer!
The current position `x` is stored as a complex number. For each movement, the program checks the list of visited positions `l`, and truncates the redundant moves appropriately.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 40 bytes
```
⊞υ⟦ⅈⅉ⟧ＦＳ«Ｍ✳ι⊞υι⊞υ⟦ⅈⅉ⟧≔…υ⊕⌕υ§υ±¹υ»⎚↑Φυ﹪κ²
```
[Try it online!](https://tio.run/##VY5Bi8IwEIXP7a/IcQLxsHtcT9IiFNJFIgUX8VDSsQ2bTUqaiCL@9mxyEHQOw5vHex8jp95J2@sYd2GZIDByPABl5Afoia7Ls3UEGjMHv/dOmREoJfeyaO0FoVYOpVfWgKIpWjwB6vV4oxWbZVGjgeomNVaTnXOiMdLhHxqPA2yVGbK38Y0Z8JrlN469R/igeRgJCfMoK429gyR36SkPX93MyFZpjy5XWjsEbeGXkc/UWcdY806IvGrOuRBc8DoZXVxd9D8 "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
⊞υ⟦ⅈⅉ⟧
```
Save the current coordinates to the predefined empty list.
```
ＦＳ«
```
Loop through each character of the input string.
```
Ｍ✳ι
```
Move the cursor in that direction.
```
⊞υι⊞υ⟦ⅈⅉ⟧
```
Save the direction and the new position.
```
≔…υ⊕⌕υ§υ±¹υ
```
Truncate the list to the original appearance of the position.
```
»⎚
```
Reset the cursor (possibly due to a bug in Charcoal).
```
↑Φυ﹪κ²
```
Output the directions which didn't get truncated.
[Answer]
# [Python 3](https://docs.python.org/3/), 178 bytes
```
x=y=0;c=[[0,0]];a='';t='UDLR';u=['y-=1','y+=1','x-=1','x+=1']
for i in input():
 exec(u[t.index(i)])
 if[x,y]in c:f=c.index([x,y]);a=a[:f];c=c[:f]
 else:a+=i
 c+=[[x,y]]
print(a)
```
[Try it online!](https://tio.run/##LU6xCsMgFNz9CjeVpCWlm@Ftjk5CJnEQq1QoaUgN6NdbTQuPd9y9495tJT3f673WDAWm2YHW0zgZM1sgZE5AFiEVmQ/QpFzgRkZShhPyj@XODArvHUcc1zbbkSjjCPvsHT10usb14TONzDCEY9B5LKYZHQ/g/rdTY@2l1TyYVsJ1bBGvj@d2gIiwG1qzbjNo2@OaqGW1Crko1ZeQUiollRRNWL4 "Python 3 – Try It Online")
Keeps track of visited coordinates and removes letters between duplicate coords.
[Answer]
# [R](https://www.r-project.org/), ~~208~~ 205 bytes
```
u=function(a){s=function(x)unlist(strsplit(x,''))
m=match
d=s(a)
l=length(d)
for(i in 1:l)for(j in i:l)if(l&!sum(m(d[k<-i:j],s("L R"),2)-2)&!sum(m(d[k],s("D U"),2)-2))return(u(d[-k]))
paste(d,collapse='')}
```
[Try it online!](https://tio.run/##XY87a8QwEIR7/QrHRW4FdpErj6hTqWpBVbjC@JHTnSwZPeAg5Lc7K5PHOSoE882OdhTW7Kz3i1izmLLrk/EOOv4R/9Sd04iJCWIKcbEmwb05HDhns5i71F/YICJFmBV2dO/pAgNnkw9gKuOql5PlRVyLMCTMBPb5KeYZZhjebq@tOV3PTYRaVVjz5sjbI3/wN0tW@sfiYUw5OMhktrcztVi6mEYYmt5b2y1xFNTt8/tXUGuFGinNfgFKJXdE0UFEtUf6P9OUpKCSj1AqjVguuT2iUEkC@32aLBqhZNksy2QBRMjZyq1f "R – Try It Online")
Recursive function: starting at each position in the string, check whether there are equal numbers of L+R and of U+D in the range up to each subsequent position. If so, then this is the first left-to-right loop, so delete this and call the function using the result. Otherwise, there are no loops, so output whatever is left. 
Frustratingly, R is not particularly golfy at string-handling (at least with my ability), and one-third of the code is ~~wasted~~ used splitting strings into characters... so:
# [R](https://www.r-project.org/)+stringr, 155 bytes (or [R](https://www.r-project.org/) 172 bytes)
```
u=function(d,l=nchar(d),s=substring){
for(i in 1:l)for(j in i:l)if(l&all(!diff(str_count(e<-s(d,i,j),s("UDLR",1:4,1:4)))[-2]))return(u(str_remove(d,e)))
d}
```
[Try it online!](https://tio.run/##XY5Ba8MwDIXv@RVdDkOG9NCxU2luPvok8KmMkSZ2p@LaRYkLY@y3Z3LKYJlBhvdJ70k8Bzpxx58wTkzxzKrKMaR0a@fc@hz7iVKEoQlt7D86hkE1Yzvm02NafVU@MdCG4ma3D6qISxEkgjyE5y4EeBrI@5L/3qccJ3CH7SiR1FwkDGqrDdbNbv9aSil13L68KcVuyhwhLz5213R34nHSr4bv@XGjeA1atPXv0QJQG70iRh4imjWy/5kVpxiN/gu1sYjl00uIQaMFrPdZacmIOMtmXSYLECKd5bj5Bw "R – Try It Online")
Exactly the same approach, but using `stringr` library to work directly on the string instead of splitting into characters. 
[Answer]
# [Python 2](https://docs.python.org/2/), 98 bytes
```
r=""
x,=l=0,
for c in input():x+=1j**(ord(c)%15);l+=x,;r+=c;n=l.index(x);l=l[:n+1];r=r[:n]
print r
```
[Try it online!](https://tio.run/##NY3BCsMgDIbvfQoRBm0tYw52qeTm0VPA0@jJOtohtkjH3NN3sWNBwu@Xj2T9bNMSr/t7moNnsvfZO875noDzKncQ4NJVjyUxx@ZIb31tddNnAfLZtvWSxto1J3lrVBCQO5UEOBUhnOc4@lxn4hDufRRyUAkSpaFa0xw3lvZyhluDFi2vuEVt9JEMFSKaX7T/bMkgwejy0cYilqYP2aDRBH57LCEakVk26mIUQIQmx7Ev "Python 2 – Try It Online")
Instead of branching on whether the current position `x` has appeared before, we just look for where it first appeared and truncate to right after that. If it never appeared before, we find the current appearance, so nothing gets cut off. The `ord(c)%15` is from a suggestion by Jonathan Allan.
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~168~~ ~~164~~ ~~163~~ ~~126~~ 125 bytes
```
l=[p:=0]
n=""
for s in input():
 if(p:=p+1j**(ord(s)%15))in l:x=l.index(p);l=l[:x+1];n=n[:x];p=l[x]
 else:l+=[p];n+=s
exit(n)
```
[Try it online!](https://tio.run/##NY5Ba8QgEIXv/goRCroppaEsFIM3j54GPAUPW@JSizUSXXB/fTom1IM83/uceflZv9f08Zm3vfpSC1WUzswasGDZK7OgjT6UwQMA5pT2X1skEDC6P7SxAP3SB2zAaDTOORYtjJDsE3UnuoEOJn2ZI71AWLDBlYSUHxVVvP1@LTdJj27zCbg9qjlL9e5IUoyR@7rRQkOixycuJKHhzhHIw/hzufB1W3gRL@NVCISibCq@hbT4xrOYooqzbMPopqQSKjdldJoj1MfiZRxwFWaDKsS3UHkS@/4H "Python 3.8 (pre-release) – Try It Online")
Assigns a complex number to go up, down, left right on the complex plane. Then iterates over the given path S and either adds the new point to the path in the list of points `l` and the result string `n` or if it detected a loop from a previous index up until the current character, it slices the characters and points that created the loops out of the lists.
-35 thanks to @JonathanAllan!
[Answer]
# [Wolfram Language](https://www.wolfram.com/language/), ~~101~~ 100 bytes
```
StringJoin[Characters@#/.(r={"L"->-"R","U"->-"D"})//.{a___,x__,b___}/;Tr@{x}==0->{a,b}/.Reverse/@r]&
```
[Try it online!](https://tio.run/##PY1BC8IwDIXv/owKotCt3mWjYE@Sg0R7EhmddG6HTahFBqW/faZzGEj48vJ46Y1vbW989zBTU0wX77rheXp1w@3YGmce3rq3XIt864rAgGVlxpBxpmdSLO6EyIOpqoqP1DVBFIerk2GMRbHPymB4HUWO9kNBVkh330xn@uGFbIQMK6YBNWrGiVCB@iFQISIsrP@LJhN5QM2bAo2Yhpr9gKBIWMI0aXQjb4pVyZIEUuiSXsbpCw "Wolfram Language (Mathematica) – Try It Online")
With some fancier formatting and comments:
```
StringJoin[                                       (*reconvert to input format*)
  Characters@#                                    (*split into characters*)
  /. (r = {"L" -> -"R", "U" -> -"D"})             (*map L to -R and U to -D*)
  //. {a___, x__, b___} /; Tr@{x} == 0 -> {a, b}  (*delete runs that sum to 0*)
  /. Reverse /@ r                                 (*convert -R and -D back to L and U*)
]&
```
This takes a similar method to some of the others, deleting runs that sum to zero, but this one does it by replacing L and U with negative R and negative D respectively.
Another **100 byte** solution that uses a similar but distinct technique, using [SequenceReplace](http://reference.wolfram.com/language/ref/SequenceReplace.html):
```
StringJoin@SequenceReplace[Characters@#/.(r={"L"->-"R","U"->-"D"}),{__}?(Tr@#==0&)->{}]/.Reverse/@r&
```
[Try it online!](https://tio.run/##PY3BCsIwDIbvPkYHMmFbfYHNgj1JDhrtSWSUkenATa3Vy9izz3SKOYT///Mlaa2/UGt9U9mxzse9d0133tyaTu3p8aKuIqT71VZ0XF@ss5Un91SRzGKX9wJEWqQCRSLMpLQYFklflsMqPjgV5flyvkiLfjjJDOnNmySVm49b/uGlqqXqZ8IAGjQiYYUa9FcCFyLCT5u/MQwxA3pyGgxiaHriAUFz8DtmOOMZs@GsDkgIOOFJeDlIuXs15McP "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 44 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
gU0ˆÇ5%v1X‚Â(ìyè¯θ+ˆ¯¤kÐV¯gα<‚Xª£ιнJ¯Y>£´vyˆ
```
Ugh.. This can definitely be golfed substantially, but it works..
Inspired by both [*@Arnauld*'s JavaScript answer](https://codegolf.stackexchange.com/a/205221/52210) and [*@OlivierGrégoire*'s Java answer](https://codegolf.stackexchange.com/a/205240/52210), so make sure to upvote them!
[Try it online](https://tio.run/##AVUAqv9vc2FiaWX//2dVMMuGw4c1JXYxWOKAmsOCKMOsecOowq/OuCvLhsKvwqRrw5BWwq9nzrE84oCaWMKqwqPOudC9SsKvWT7Co8K0dnnLhv//VUxSVVJV) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeXhCf/TQw1Otx1uN1UtM4x41DDrcJPG4TWVh1ccWn9uh/bptkPrDy3JPjwh7ND69HMbbYDyEYdWHVp8bueFvV6H1kfaHVp8aEtZ5em2/7W1Ooe2/I9WCvUJCg0KVdJRCg1y8XEBs3yAICgoyAfCDIWxQ4EqgAp8XEAcF5/QoCAQ4QJW7BPk4wIUgJgTChQCSgFVgkx0AakACQBFgDIgy2IB).
**Explanation:**
```
g                # Get the length of the (implicit) input-string
 U               # Pop and store it in variable `X`
0ˆ               # Add 0 to the global array
Ç                # Convert the (implicit) input-string to an integer-list of codepoints
 5%              # Take modulo-5 on each
   v             # Loop over each integer `y`:
    1X‚          #  Pair 1 with the length `X`: [1,length]
       Â         #  Bifurcate it (short for Duplicate & Reverse copy)
        (        #  Negate the values: [-length,-1]
         ì       #  Prepend the lists together: [-length,-1,1,length]
          yè     #  Index `y` into this quadruplet
            ¯θ+  #  Add the last item of the global array to it
               ˆ #  And pop and add it to the global array
    ¯            #  Push the global array
     ¤           #  Push its last item (without popping)
      k          #  Get the first index of this last item in the global array
       Ð         #  Triplicate this index
        V        #  Pop and store one copy in variable `Y`
         ¯g      #  Push the length of the global array
           α     #  Take the absolute difference with the index
            <    #  Decrease it by 1
             ‚   #  Pair it with the index
              Xª #  And append length `X`
    £            #  Split the string into parts of that size
                 #  (which uses the implicit input-string in the very first iteration)
     ι           #  Uninterleave it
      н          #  Only leave the first part of two strings, removing the middle part
       J         #  Join this pair together
    ¯            #  Push the global array again
     Y>          #  Push `Y` + 1
       £         #  Only leave the first `Y`+1 values of the global array
        ´        #  Empty the global array
         v       #  Loop over the `Y`+1 values of the global array:
          yˆ     #   And add each of them back the global array
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~126~~ 120 bytes
```
$x=$y=0
switch -r(,'-'+$args){U{$y++}D{$y--}R{$x++}L{$x--}.{$g="$g$_$x-$y"-replace"(?<=($x-$y)).*\1$"}}
$g-replace'\d|-'
```
[Try it online!](https://tio.run/##hZFRT8IwEMff@yma5bSbrESfdRFjE1@aaEr6BIbgqEMzBNcRIKWffV43przZh13u97/fddk2652p7NKUZQPvNKOugX0Gh@ya2N1HnS8pr@KUcTaAeVXYxGkHh8HACyyce@Vgj53Egt3QQZFFUMAMWzhEvDKbcp6bKL6/y@KWJcnwanoDkfcEij5n08WRs8YTMooJSWOmpdJKs5QyHWrSMiWk6KDomcSjlJIBSvnL9BmUWp18XICiFG3QMYGpCg/RLpJKCgTtHb2FhkRHoxjuF2EyACQ6LO/e8v@phJCEHukFdYTigXy9Ws2/FjalYPYbk9dmgV8fZl1aGbstawSX@FNG/WybTV7Gj1tbr1fPb5@ovY4cHW/z3Fgb/JPIzfff3lsqHp7OQk988wM "PowerShell – Try It Online")
The script:
1. injects `$x-$y` to input string like `-0-0U0-1U0-2R1-2U1-3`
2. removes substrings between same coordinates
3. removes digits and minus chars
Less golfed:
```
$x=$y=0
switch -regex (,'-'+$args){
    U {$y++}
    D {$y--}
    R {$x++}
    L {$x--}
    . {$g="$g$_$x-$y"-replace"(?<=($x-$y)).*\1$"}
}
$g-replace'\d|-'
```
]