[Question]
  [
This is a 2-dimensional version of [this question](https://codegolf.stackexchange.com/q/71877/9288).
Given a non-empty 2-dimensional array/matrix containing only non-negative integers:
$$ \begin{bmatrix}
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & {\color{Red}0} & 0 & 1 & 0 \\
{\color{Red}0} & {\color{Red}0} & 0 & 0 & 1 \\
{\color{Red}0} & {\color{Red}0} & 1 & 1 & 1 \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0}
\end{bmatrix} $$
Output the array with surrounding zeroes removed, i.e. the largest contiguous subarray without surrounding zeroes:
$$ \begin{bmatrix}
0 & 1 & 0 \\
0 & 0 & 1 \\
1 & 1 & 1
\end{bmatrix} $$
## Examples:
$$ \begin{bmatrix}
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & {\color{Red}0} & 0 & 1 & 0 \\
{\color{Red}0} & {\color{Red}0} & 0 & 0 & 1 \\
{\color{Red}0} & {\color{Red}0} & 1 & 1 & 1 \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0}
\end{bmatrix} 
\mapsto
\begin{bmatrix}
0 & 1 & 0 \\
0 & 0 & 1 \\
1 & 1 & 1
\end{bmatrix}
$$
```
Input:
[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 1], [0, 0, 0, 0, 0]]
Output:
[[0, 1, 0], [0, 0, 1], [1, 1, 1]]
```
$$ \begin{bmatrix}
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & 0 & 0 & 3 \\
{\color{Red}0} & 0 & 0 & 0 \\
{\color{Red}0} & 5 & 0 & 0 \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0}
\end{bmatrix} 
\mapsto
\begin{bmatrix}
0 & 0 & 3 \\
0 & 0 & 0 \\
5 & 0 & 0
\end{bmatrix}
$$
```
Input:
[[0, 0, 0, 0], [0, 0, 0, 3], [0, 0, 0, 0], [0, 5, 0, 0], [0, 0, 0, 0]]
Output:
[[0, 0, 3], [0, 0, 0], [5, 0, 0]]
```
$$ \begin{bmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{bmatrix}
\mapsto
\begin{bmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{bmatrix}
$$
```
Input:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
$$ \begin{bmatrix}
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0}
\end{bmatrix}
\mapsto
\begin{bmatrix}
\end{bmatrix}
$$
```
Input:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Output:
[]
```
$$ \begin{bmatrix}
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0} \\
1 & 1 & 1 & 1 \\
{\color{Red}0} & {\color{Red}0} & {\color{Red}0} & {\color{Red}0}
\end{bmatrix}
\mapsto
\begin{bmatrix}
1 & 1 & 1 & 1
\end{bmatrix}
$$
```
Input:
[[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]]
Output:
[[1, 1, 1, 1]]
```
$$ \begin{bmatrix}
{\color{Red}0} & 1 & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & 1 & {\color{Red}0} & {\color{Red}0} \\
{\color{Red}0} & 1 & {\color{Red}0} & {\color{Red}0}
\end{bmatrix}
\mapsto
\begin{bmatrix}
1 \\
1 \\
1
\end{bmatrix}
$$
```
Input:
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]
Output:
[[1], [1], [1]]
```
$$ \begin{bmatrix}
1 & 1 & 1 & 1 \\
1 & 2 & 3 & 1 \\
1 & 1 & 1 & 1
\end{bmatrix}
\mapsto
\begin{bmatrix}
1 & 1 & 1 & 1 \\
1 & 2 & 3 & 1 \\
1 & 1 & 1 & 1
\end{bmatrix}
$$
```
Input:
[[1, 1, 1, 1], [1, 2, 3, 1], [1, 1, 1, 1]]
Output:
[[1, 1, 1, 1], [1, 2, 3, 1], [1, 1, 1, 1]]
```
  
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 42 bytes
```
#&@@CellularAutomaton[{,{},0{,}},{#,0},0]&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE7875@WFh1cmVeSWGFllZyfG2vNlWar8V9ZzcHBOTUnpzQnscixtCQfqDg/L7pap7pWx6Bap7ZWp1pZxwDIjlX7r2nNFVCUmVcSneagHKum71DNxVVdbaCjgEC1OgoIAUN0AZAYQsAQgtBVGACtRDEWRYExqnIozxSLSqg5QCuMoNpMwArNQExzHQULHQVLFKuQdCMza7m4av8DAA "Wolfram Language (Mathematica) – Try It Online")
Cellular automata are indeed the answer to [life](https://www.wolfram.com/language/gallery/implement-conways-game-of-life/), [the universe](https://xkcd.com/505/), and [everything](https://cs.stackexchange.com/q/4779).1
### How?
`CellularAutomaton` accepts an input array and an optional background value. Thus, `{#,0}` specifies that a cellular automaton rule should be applied to the input, assuming a background of `0`s.
A neat thing here is that `CellularAutomaton` crops the output so that no border of background cells is present (because otherwise the output lies on an infinite plane).
The code applies the rule `{Null, {}, {0, 0}}` -- applying the head `Null` to the 0-radius neighbor of each cell (i.e. only the center: the cell itself) -- exactly `0` times. The result of this is the original input, but with background removed (i.e. cropping out surrounding `0`s).
---
1. See the bytecount of my answer? ;)
[Answer]
# JavaScript (ES6), 98 bytes
```
(a,z)=>(g=A=>A.slice(A.map(m=M=(r,i)=>M=(z?a:r).some(n=>z?n[i]:n)?1/m?i:m=i:M)|m,M+1))(a).map(z=g)
```
[Try it online!](https://tio.run/##nVHLboMwELz3K3z0qi7EaZsH0oL4AL4A@WBRghxhO4KqB9R/J@AEIWgiUFd7WI/HM2P7LH9knVXq8v1m7FfenrClkjWAIS0wxjD26lJlOY09LS9UY4K0Yqrb7oYmkkEFXm11Tg2GTWRSJQIDEfd1pAKNKkjgV7PklQNQCU6iwQLazJralrlX2oKeaJpuGBlbMDICfA702AjwW88ZGyEAiO8TJz3VcOThnHh5HmUi@j61uK8@HzBv3rMaosyU@nHQ@BulS7i98z@c164f94wcGDk@cllVLsqC9NpXWXHzpShLXvzJJ//HKyWjGhGivQI "JavaScript (Node.js) – Try It Online")
### How?
To overcome the lack of a *zip* built-in, we define a function ***g()*** that is able to operate on either the rows or the columns of the input matrix ***a[ ]***, depending on the value of the global flag ***z***.
***g()*** looks for the minimum index ***m*** and maximum index ***M*** of either non-empty rows (if ***z*** is undefined) or non-empty columns (if ***z*** is defined) and returns the corresponding *slice* of either the matrix itself or a given row of the matrix.
To summarize:
* we first remove rows by invoking ***g()*** on the matrix with ***z*** undefined
* we then remove columns by invoking ***g()*** on each row with ***z*** defined, which leads to this rather unusual `.map(z=g)`
### Commented
```
(a, z) => (               // a[] = input matrix; z is initially undefined
  g = A =>                // g() = function taking A = matrix or row
    A.slice(              //   eventually return A.slice(m, M + 1)
      A.map(m = M =       //     initialize m and M to non-numeric values
        (r, i) =>         //     for each row or cell r at position i in A:
        M = (z ? a : r)   //       iterate on either the matrix or the row
        .some(n =>        //       and test whether there's at least one
          z ? n[i] : n    //       non-zero cell in the corresponding column or row
        ) ?               //       if so:
          1 / m ? i       //         update the maximum index M (last matching index)
                : m = i   //         and minimum index m (first matching index)
        :                 //       otherwise:
          M               //         let M (and m) unchanged
      ) | m,              //     end of map(); use m as the first parameter of slice()
      M + 1               //     use M+1 as the second parameter of slice()
    )                     //   end of slice()
  )(a)                    // invoke g() on the matrix with z undefined
  .map(z = g)             // invoke g() on each row of the matrix with z defined
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), 3 bytes
```
JYa
```
[Try it online!](https://tio.run/##y00syfn/3ysy8f//aAMdBQSyRrANUbkgEWuElCESF4piAQ "MATL – Try It Online") Or [verify all test cases](https://tio.run/##y00syfmf8N8rMvG/uq6ueoRLyP9oAx0FBLJGsA1RuSARa4SUIRIXimK5orEaZGyNboEphhqQZqCRRmDVJmAVZtYK5joKFjoKlrgMRjUAAA).
### Explanation
```
J      % Push 1j
Ya     % With complex 2nd input, this unpads the matrix in the
       % 1st input (implicit). The unpad value is 0 by default
       % Display (implicit)
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~62~~ 61 bytes
```
f.f.f.f
f=reverse.foldr(zipWith(:))e.snd.span(all(<1))
e=[]:e
```
[Try it online!](https://tio.run/##y0gszk7NyfmfrmCrEPM/TQ8MudJsi1LLUouKU/XS8nNSijSqMgvCM0syNKw0NVP1ivNS9IoLEvM0EnNyNAztNDW5Um2jY61S/@cmZuYBjSkoyswrUVBRSFeI5lKINtCBwlgdMM8QhWeAxjPCIhf7/19yWk5ievF/3QjngAAA "Haskell – Try It Online") 
`foldr(zipWith(:))e` with `e=[]:e` is a [slightly shorter `transpose`](https://codegolf.stackexchange.com/a/111362/56433), and `snd.span(all(<1))` drops leading lists of zeros from a list of list. As `transpose` followed by `reverse` on a 2D list equals an rotation by 90°, the code `f.f.f.f` is just four times *drop leading lists of zeros and rotate*.
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 13 bytes
```
V2=.sCQ]m0Q;Q
```
[Try it online!](https://tio.run/##bUxLCoMwEF03pxik4CZ@ov2i7aYnyKYbycKalAjWiArF06cxFatQBmbem/d55J3UUuQcvMIjkKbgCvV04QqF4kLfo4vf3Sh7hTSh2igIvWVZCWhtpIWqrEUCXKFNM/RS1TEEqumDkdjlN4NtMs0pONvR7iCuaqGzLMTTMDxhssCGTZiMs/iHjKE5Pf/jn8Oi/Ur9ZgiOrG9n1IO5R3zC579t6@QH "Bash – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 10 bytes
```
œr€0z0Uµ4¡
```
[Try it online!](https://tio.run/##y0rNyan8///o5KJHTWsMqgxCD201ObTw/@H2o5Me7pzx/390tIGOAhTF6iggeMYoPJicKRaVBrGxAA "Jelly – Try It Online")
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), ~~24~~ ~~22~~ ~~20~~ 19 bytes
```
{s.h+>0∧.t+>0∧}\↰₁\
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r/v7pYL0PbzuBRx3K9EghdG/OobcOjpsaY//@jow10FKAoVkcBwTNG4cHkTLGoNIiN/R8FAA "Brachylog – Try It Online")
Outputs the result matrix as an array of arrays, or false for empty output. 
*(Thanks to @Fatalize for suggesting inline predicate and saving 1 byte.)*
### Explanation
**Predicate 0 (Main):** 
```
{...}     Define and call predicate 1 to remove all-zero rows
  \       Transpose the result
   ↰₁     Call pred 1 again, now to remove all-zero columns
     \    Transpose the result to have correct output orientation
```
**Predicate 1:**
```
?s.h+>0∧.t+>0∧
  .           output is
 s              a subsequence of the rows of
?              the input (implicit)
   h          also, output's head element (first row)
    +>0        has a sum > 0 (i.e. has at least one non-zero value)
       ∧.t+>0  and similarly the output's tail element (last row)
∧              (don't implicitly unify that 0 with the output)
```
[Answer]
# [R](https://www.r-project.org/), ~~96 100~~ 97 bytes
```
function(m)m[~m,~t(m),drop=F]
"~"=function(x,z=seq(r<-rowSums(x)))z>=min(y<-which(r>0))&z<=max(y)
```
[Try it online!](https://tio.run/##jVFdT8JAEHzvr9icidmL1wj4nVDe9AcgPkFjoB6lSXutd9dQUPnruNdWEUIiyV1yM92Z2d3q7RmMSq0MFEUU@8auUgnG6kTFkCibwxCyKcEK5rkGK42FaGoklEZ6TtHT0PdhXqrIJrnCisOHB1A5MjblDBkwwZioOLHqVedL4z6lUsV2YVDLmNyjhTRYCYgJyqrQyCaTMRNQcc7Bh24tjfK0luJ/WvGjvIAuh8s21XmUWe1A09k8wVKlibFIyBRpYrFpN/qkbLohubDaSbgJyI8cmk2gMxKtr2hbEzBbEYYARsOXR@59ed7chW1/V5PxbLzJxMbSS7zpvAieQo9tWLBbnlgHRr6j7vtk9Uwp6AZZD4IsUbjq@8tFEi1QDzqcn6/7QTatcMW3c2x@BLLxuCNgd0IBO6J7SDhuR3Sbc1jRCUOanWY5mrFXfbWvbdHNkcpjphTeaz2ua9Wte94JuBfwcHoTJwX9Ke3toat94fYb "R – Try It Online")
The `~` helper takes a non-negative vector and returns a vector with `FALSE` for the "exterior" `0`s of the vector and `TRUE` for positives and any "interior" `0`s. This function is applied to the row and column sums of the input matrix.
`~` and `!` [use R's parser treatment of operators.](https://codegolf.stackexchange.com/a/164914/79980)
Corrected as per @DigEmAll's comment, but with some bytes golfed back from @J.Doe
[Answer]
# [R](https://www.r-project.org/), ~~89~~ 79 bytes
```
function(m,y=apply(which(m>0,T),2,range)){y[!1/y]=0;m[y:y[2],y[3]:y[4],drop=F]}
```
[Try it online!](https://tio.run/##jVDLbsIwELznK7bpxVYXkQB9N721H4DoKVgVpCZESpzIdkQsyrdTO6RFoFStZEue8c7M7sr9JcxqKRRUVZIOlDY5B6VlJlLIhC5hCsXCwgZWpQTNlYZkoTjUintOMZLwNIBVLRKdlYI0FLYeQOPIVNVL4oOPvo8Ntax4l@VGua@ci1SvFZE8te7JmivSIKQW8qaSxJ/PYx@hoZTCAMJWmpR5KyV/afFbeQUhhWGX6jzqonWw0@kyI7XIM6WJRarKM00O7SafNtteZl381gndBNbPOhw2QZwRdr7YtYawNBZDBLPp2wv1dp63cmH7n9UUaKJFVeWGbNZZsibFc4AziiOUC5FySrcmvgiHhkXBYxGbBxOPGJp4zOxrwvBDllX0ynb7FTmsnfhxHCAcD0M4EuE54bgjER7OeUXAmJ3Udt6bcVI9PtV26Lqnss/Uho86j0mrunHPW4Q7hPv/N/F30Glp@Mvk/cLwJKMfOeH@Cw "R – Try It Online")
Thanks to @ngm for the test cases code, and @J.Doe for saving 10 bytes !
* I had to add `drop=F` parameter due to the default R behavior turning single row/col matrix into vectors...
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), ~~17~~ 15 bytes
```
{⍉⌽⍵⌿⍨∨\∨/×⍵}⍣4
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@ob2pm/qO2CQb/04Bk9aPezkc9ex/1bn3Us/9R74pHHStigFj/8HSgUO2j3sUm//@rp2QWF@QkVqoDtSZXqqek5RWrc5VANG991LmwCMhMe9S7y0o9P1v9UXcLTHlaYmaOOlAcqKqolkvjUdtEDQMFKNSEMg0RTCAHwjQEQU0ktZolEL1wxUBZiCIUU2FajDWRRUyRpRBmIZRpakCUQMwyVDACyZgA9ZlpapgrWChYQvVgk8FqP4ptIOpR7xYDAA "APL (Dyalog Classic) – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), 71 bytes
Returns by modifying the input. A list should be passed as input.
```
def f(a):exec'while a and 1>sum(a[-1]):a.pop()\na[:]=zip(*a)[::-1]\n'*4
```
[Try it online!](https://tio.run/##fZDLCoMwEEXXzVfMzqSkxVj7CljwO2IWoSoG2hispY@fT9VaRFsKs5i5c@ZeGPuoi9IEzqVZDjlWhGf37OjdCn3KQIEyKbDD5XrGSiyYJFwtbWkxSYwSXEZPbfFcEcF5s0yMNw9dHAk0E8KnMJSkMAhsKrTaILB3TQlfSjr2HRGrMd9P6x/kx6gJCfq7sCM3bbulsKOw/x/2ZYgkQnlZNf/SBmKOukcisJU2Nai@cS8 "Python 2 – Try It Online")
---
# [Python 2](https://docs.python.org/2/), 77 bytes
This also modifies the input, but it works....
```
def f(a):exec'while a and 1>sum(a[-1]):a.pop()\na=zip(*a)[::-1]\n'*4;return a
```
[Try it online!](https://tio.run/##fZDdDoIwDIWv3VP0jo1MA/g/g4nPMXbR6AgkOpYJ8eflERVDQGPSi/b06zlJ7a3MChPV9UGnkFJkQl/13rtk@VEDApoDhNtzdaIox6FiAie2sJQlBuN7bqmPTArRbBLj@bON02XlDGC9iyUZSRlw6Epx6IRwKDy1TgjfNSQCpXjft0dM@3w7zX@QH6MmJGrvZi9y8WyXHFYc1v/DvgyJIiQtXPO13MBOEHBxSk9oaVnZo@bIGAHrclOCa5v6AQ "Python 2 – Try It Online")
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 66 bytes
```
If[Max@#>0,ImageCrop@Image[#~ArrayPad~1,r="Real"]~ImageData~r,{}]&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n2ar8d8zLdo3scJB2c5AxzM3MT3VuSi/wAHMilaucywqSqwMSEypM9QpslUKSk3MUYqtA0u6JJYk1hXpVNfGqv3X5AooyswriU6Lrq420FGAolodBQTPGIUHkzPFotKgtjY2FtNAJDXITFS1hjpAWKsDpI2gNIgPVPMfAA "Wolfram Language (Mathematica) – Try It Online")
Now works by padding the array with zeroes (thanks @JungHwanMin)!
A second thanks to @JungHwanMin for saving 4 bytes
[Answer]
# [J](http://jsoftware.com/), 24 bytes
```
(|.@|:@}.~0=+/@{.)^:4^:_
```
[Try it online!](https://tio.run/##bVHLbsIwELz7K0YowkQlBpekBZdEkSr11FOvlahQHjRIJIjm0KrAr6e2sSGN4pW9692ZHT@2zYCB5ggFKMaYQsjpMTy/vb40oyOLjyI@sfM0vJvEv8xdCX8lPhqXbNJip0kjRaOuXM@g3xTbqii/6kNRbvAuMBBDFuFpEjuE1IkirIUJ5DrGMkAAR0paM47fQrUxjttQW6eP3@pj3AztTNAu/WfPJNSRze8VxZfIB@ARcyw6KK3Rl7MqlzPyXgjvkfW1rLnZRZ8TQnZVuU6RZnlRZlAveGJ1QoAs@axAl2FnRNTWfmyg/@e6o/C8CDfUHiFD3kXvr3BK3OYP "J – Try It Online")
## Explanation
```
(|.@|:@}.~0=+/@{.)^:4^:_
            +/                sum
              @               of
               {.             the first row
          0=                  is zero? (1 = true, 0 = false)
       }.~                    chop off that many rows from the front
 |.@|:@                       rotate by 90 deg (transpose then reverse)
(                )^:4         repeat this process 4 times (rotating a total of 360 deg)
                     ^:_      fixpoint - repeat until no change
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 12 bytes
```
Ṗ§Ṫ¬ȧƲ¿UZµ4¡
```
[Try it online!](https://tio.run/##y0rNyan8///hzmmHlj/cuerQmhPLj206tD806tBWk0ML/x9uf9S0RuHopIc7Z/z/H82lEB1toGMQqwMmY3UgfEOoiBGSGEjEUMcQoTIWAA "Jelly – Try It Online")
As a function.
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 48 bytes
```
Nest[Reverse@Thread@#//.{{0..},a___}->{a}&,#,4]&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE7875@WFh1cmVeSWGFllZyfG2vNlWar8d8vtbgkOii1LLWoONUhJKMoNTHFQVlfX6@62kBPr1YnMT4@vlbXrjqxVk1HWcckVu2/pjVXQFFmXkl0moNyrJq@QzUXF1CtjgIU1eooIHjGKDyYnCkWlQa1tToIc5CkkJm1XFy1/wE "Wolfram Language (Mathematica) – Try It Online")
Doing it the normal way.
[Answer]
# [Husk](https://github.com/barbuz/Husk), 11 bytes
```
!5¡(T0mo↔↓¬
```
[Try it online!](https://tio.run/##yygtzv7/X9H00EKNEIPc/EdtUx61TT605v///9HRBjpgGKsDZRnDWRAxUxRZg9hYAA "Husk – Try It Online")
I feel like some bytes could be shaved off by shortening the `!5¡` part.
### How it works
```
!5¡(
```
Repeatedly apply the function explained below, collecting the results in an infinite list. Then, retrive the \$5^{\text{th}}\$ element. In other words, apply the function to the input 4 times.
```
mo↔↓¬
```
Map over the current version of the input and: reverse each, after having dropped the longest prefix consiting of zeroes only (dropping this prefix is performed by using Husk's `↓`, which is a function that crops the longest run of consecutive elements from the beginning of the list that yield truthy results when ran through a function, namely `¬`, logical not).
```
T0
```
Transpose, replacing missing entries with **0**.
[Answer]
# [Retina](https://github.com/m-ender/retina/wiki/The-Language), 87 bytes
```
/.\[(?!0,)/^+`\[0, 
[
/(?<! 0)]./^+`, 0]
]
\[(\[0(, 0)*], )+
[
(, \[0(, 0)*])+]|\[0]]
]
```
[Try it online!](https://tio.run/##bYwxDoAgDAD3vgI2KgSqcTThIVCjg4OLg3H071gmEkPS5a7X3sdzXvtYSvA5majJYVjtlhM5BQmCiYtWhOyrdYoYGCSUvRHCgZ1CK6FQc2j5FWKJS0n1VRs5qGL6C@qLuVvwBw "Retina – Try It Online") Explanation:
```
/.\[(?!0,)/^+`
```
Until at least one row doesn't begin with zero...
```
\[0, 
[
```
... remove the leading zero from each row.
```
/(?<! 0)]./^+`
```
Until at least one row doesn't end with zero...
```
, 0]
]
```
... remove the trailing zero from each row.
```
\[(\[0(, 0)*], )+
[
```
Remove leading rows of zeros.
```
(, \[0(, 0)*])+]|\[0]]
]
```
Remove trailing rows of zeros, or the last remaining zero.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 48 bytes
```
Ｆ⁴«Ｗ∧θ¬Σ§θ±¹Σ⊟θ¿θ≔⮌Ｅ§θ⁰Ｅθ§§θνλθ»⪫[]⪫Ｅθ⪫[]⪫ι, ¦, 
```
[Try it online!](https://tio.run/##bY3LCoMwEEXX@hWDqxFSsMWdK5cttEi7DC6CRg3YxFdtofTb0/hoETHM4nBmcm9SsCZRrNQ6Uw2g78Lbtp6FKDlgKFOsCVxUh7fHHcPuKFP@GhXPWcdx744PokbI6SZSFdZGBbYlMjAIYduKXOKV97xpOZ5ZtQzyXAKDMvizi60023JoIFCbyI89FZ2UkOjQ2CEw4hyw1oKAQWf8PkOgNaXUM73/iQkM4rAW3rbwNy/iWO/68gs "Charcoal – Try It Online") Link is to verbose version of code. Includes 15 bytes for formatting. Explanation:
```
Ｆ⁴«
```
Repeat 4 times.
```
Ｗ∧θ¬Σ§θ±¹
```
Repeat while the array is not empty but its last row sums to zero...
```
Σ⊟θ
```
Remove the last row from the array and print a line of the length of its sum, i.e. nothing.
```
¿θ≔⮌Ｅ§θ⁰Ｅθ§§θνλθ»
```
If the array isn't empty then transpose it.
```
⪫[]⪫Ｅθ⪫[]⪫ι, ¦, 
```
Format the array nicely for display. (Standard output would be `Ｉθ` instead.)
[Answer]
# JavaScript, 144 140 129 127 bytes
```
w=>(t=w=>(q=(s=w=>w.some((r,j)=>r.find(e=>e,i=j))?w.slice(i).reverse():[[]])(s(w)))[0].map((e,j)=>q.map((e,i)=>q[i][j])))(t(w))
```
140 -> 129 bytes, thanks @Arnauld
### Algorithm
* Do twice:
	+ Find first non-zero row
	+ Slice off preceding rows
	+ Reverse
	+ Find first non-zero row
	+ Slice off preceding rows
	+ Reverse
	+ Transpose
```
f = w=>(t=w=>(q=(s=w=>w.some((r,j)=>r.find(e=>e,i=j))?w.slice(i).reverse():[[]])(s(w)))[0].map((e,j)=>q.map((e,i)=>q[i][j])))(t(w));
w1 = [[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 1], [0, 0, 0, 0, 0]];
w2 = [[0, 0, 0, 0], [0, 0, 0, 3], [0, 0, 0, 0], [0, 5, 0, 0], [0, 0, 0, 0]];
w3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
w4 = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
console.log(f(w1).join("\n"));
console.log(f(w2).join("\n"));
console.log(f(w3).join("\n"));
console.log(f(w4));
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~118~~ 116 bytes
```
f=lambda a,n=4,s=sum:n and f(zip(*a[max(i for i in range(len(a))if s(s(a[:i],()))<1):][::-1]),n-1)or(s(s(a,()))>0)*a
```
[Try it online!](https://tio.run/##fZDdasMwDIWv56fQpVxUiLvuz8yFPofxhUbj1ZA4xklh68unTZoR0o2BLqSjT0dw0nd3bOKm772puP44MDBFs6XWtKdaR@B4AI/nkHDFtuYvDOCbDAFChMzxs8SqjMhSBg8ttshWB0copXxXUjur9Vo5SXGtZJNxJMbtrpAr7vfGigdrC4K5HMEsqHth0GZB3eqeKJyjpe@CeFzy0/T0B/ljdH2yme62I/k8tC8ErwRv/z/7ZSicEEOEPES41wKy8Vhzwu6UqpKuUQpIOcQO8tT0Fw "Python 2 – Try It Online")
---
Saved:
* -2 bytes, thanks to shooqie
[Answer]
# [PHP](http://www.php.net/) (>=5.4), ~~200~~ ~~194~~ ~~186~~ 184 bytes
(-6 bytes by returning `null` instead of empty array)
(-8 bytes thanks to [Titus](https://codegolf.stackexchange.com/users/55735/titus))
(-2 bytes with calling by reference thanks to [Titus](https://codegolf.stackexchange.com/users/55735/titus))
```
function R(&$a){$m=$n=1e9;foreach($a as$r=>$R)foreach($R as$c=>$C)if($C){$m>$r&&$m=$r;$M>$r||$M=$r;$n>$c&&$n=$c;$N>$c||$N=$c;}for(;$m<=$M;)$o[]=array_slice($a[$m++],$n,$N-$n+1);$a=$o;}
```
[Try it online!](https://tio.run/##hVJda4MwFH3WXxHKpVVqx9x3SeMe9tw@@GpliKQoaJRoGaP1t3c3sfWjKxvxI@fcc87NhZRJeVq9l0lpmlDzqq4II4Fp4GME9855hU4P3TFEooeuWuOqFqt3mDiUPI70F/B8LRvnuM7DxfiE2pd2@@q8Ocv/@v2ROhK4N6a5UrvDuNsA35CednsR12khiG9NIbIPkDMQzOVLuiskj@LEgohEFUjmgW93nK@4GLkPO91Z@EWjB3I6VX5JYY3geIS1BsKDGCuCQUxhgwArGwUazLMo5CsGa2pDEYQskjL6/qyyNObYOYB8Pg8dEA5sFiDmrk0hYlDQpj94KVNRf2ofOtTPPpgGnornZd1RijN4nBRkEpBwKybUNBqeVVzx/ahKi6MRkMWXtnQeZRgosa51cZG1ulao8N2MzLS46f3njopqzMY0u5z2YqsktVNRIHm1z2q87JpCl2@dORvBaFztQbJtwry2y0jSO1vRVizIr7UV2tmcfgA "PHP – Try It Online")
# How?
Finds min and max index for rows (`$m` & `$M`) and columns (`$n` & `$N`) and replaces the input with a sub array from `$m,$n` to `$M,$N` (this is a call by reference).
[Answer]
# Octave, ~~48~~ 49 bytes
```
@(a)sparse(1-min([x y v]=find(a))+x,1-min(y)+y,v)
```
[Try it online!](https://tio.run/##y08uSSxL/f/fQSNRs7ggsag4VcNQNzczTyO6QqFSoSzWNi0zLwUop6ldoQORqNTUrtQp0/yfmFesEc1loACFRLIMYzX/AwA "Octave – Try It Online")
Find nonzero points and rearrange them in a new sparse matrix.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~73~~ 63 bytes
```
->a{4.times{_,*a=a while a[0]&.sum==0;a=a.reverse.transpose};a}
```
[Try it online!](https://tio.run/##xZFNC8IwDIbv/RXBg4MRy@a3jHoT8Sx4GWVUqTjwY7SbItt@@3ROrIp6EEECIc@bUN4mKpkfiyUrGkORtmkcbqROA7QFE3BYhWsJwnd4nepkw5jjnWWq5F4qLWmsxFZHOy1zT@RFAAx8AuA7eA2OBt1HPAsG3TIeuw4nnJAAAKgUi1WahVmUxBpC2wIrJ2V9SVAbT2ajaa1Sln7AX85Xs7dUvvzOrItNbBns4wDbBnvYxc7zV/5n9iv8xmwEpd0P1tz7K1Y7vEHV@eWOihM "Ruby – Try It Online")
Edit: simplified, also the previous version crashed for all `0`s
### How it works:
* do 4 times:
	+ remove the first line while there is a first line and it's full of `0`s
	+ rotate the array clockwise by 90°
* return the array
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~22~~ 19 bytes
```
4{+|(+/&\~+/x)_'x}/
```
[Try it online!](https://ngn.codeberg.page/k#eJxLszKp1q7R0NZXi6nT1q/QjFevqNXn4iqxqlaJrqwrskpTqLBOyM+21khIS8zMsa6wrrQu0oyt5SqJ1jBQgEJrCG0IZwHZ1hARQygLDDW5FBQ0EOoMrcHymrFIhkEVG1sj+KZI4jAj4CqswbIQIwwVjIDCJkANZtbmChYKlmDFmKJY7EMx30BZR9EgFgCcqjj3)
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~78~~ 74 bytes
```
function x=f(x)
for k=1:nnz(~x)*4,x=rot90(x);x=x(:,~~cumsum(any(x,1)));end
```
[Try it online!](https://tio.run/##fY3LCoMwEEX3fsVsCknJwrT2oSFfUroQTUBaJ6CxTbvw11MVqY9C4Q7MzJ17xmQ2fSjvdYOZLQyCk5o4GmhTwU3yBPFNWke3EXOyMjYOO1M46UjC2jZryropSYov4hinlAqFue8KNoDGAiqVqxx6VgrfD0UnW4N5IujirgJNLiGDSWLq@XLsN2Ky@GwcdaVL3Mzei/WPw8/NmO/AuyEQDUdHAScGZwbxH/wK44MP "Octave – Try It Online")
### Explanation
This rotates the matrix by `90` degrees (`x=rot90(x)`) a sufficient number of times (`for k=1:... end`). The number of rotations is a multiple of `4`, so the final matrix has the original orientation. Specifically, the number of rotations is `4` times the number of zeros in the matrix (`nnz(~x)*4`).
For each rotation, if there are one or more columns on the left consisting of only zeros they are removed (`x=x(:,~~cumsum(any(x,1)))`).
What remains of the matrix after this process is output by the function (`function x=f(x)`).
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 14 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
Ç·W≈y§╗♦º{¬║8•
```
[Run and debug it](https://staxlang.xyz/#p=80fa57f77915bb04a77baaba3807&i=[[0,+0,+0,+0,+0],+[0,+0,+0,+1,+0],+[0,+0,+0,+0,+1],+[0,+0,+1,+1,+1],+[0,+0,+0,+0,+0]]%0A[[0,+0,+0,+0],+[0,+0,+0,+3],+[0,+0,+0,+0],+[0,+5,+0,+0],+[0,+0,+0,+0]]%0A[[1,+2,+3],+[4,+5,+6],+[7,+8,+9]]%0A[[0,+0,+0,+0],+[0,+0,+0,+0],+[0,+0,+0,+0]]%0A[[0,+0,+0,+0],+[1,+1,+1,+1],+[0,+0,+0,+0]]%0A[[0,+1,+0,+0],+[0,+1,+0,+0],+[0,+1,+0,+0]]%0A[[1,+1,+1,+1],+[1,+2,+3,+1],+[1,+1,+1,+1]]&a=1&m=2)
### Alternative, also 14 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
Ç·W≈x≈ƒHq♣☻»íÅ
```
[Run and debug it](https://staxlang.xyz/#p=80fa57f778f79f48710502afa18f&i=[[0,+0,+0,+0,+0],+[0,+0,+0,+1,+0],+[0,+0,+0,+0,+1],+[0,+0,+1,+1,+1],+[0,+0,+0,+0,+0]]%0A[[0,+0,+0,+0],+[0,+0,+0,+3],+[0,+0,+0,+0],+[0,+5,+0,+0],+[0,+0,+0,+0]]%0A[[1,+2,+3],+[4,+5,+6],+[7,+8,+9]]%0A[[0,+0,+0,+0],+[0,+0,+0,+0],+[0,+0,+0,+0]]%0A[[0,+0,+0,+0],+[1,+1,+1,+1],+[0,+0,+0,+0]]%0A[[0,+1,+0,+0],+[0,+1,+0,+0],+[0,+1,+0,+0]]%0A[[1,+1,+1,+1],+[1,+2,+3,+1],+[1,+1,+1,+1]]&a=1&m=2)
[Answer]
# PHP, 188 bytes
```
function f(&$a){for($s=array_shift;!max($a[0]);)$s($a);for($p=array_pop;!max(end($a));)$p($a);for($w=array_walk;!max(($m=array_map)(reset,$a));)$w($a,$s);while(!max($m(end,$a)))$w($a,$p);}
```
call by reference.
**breakdown**
```
// call by reference
function f(&$a)
{
    // while first row is all zeroes, remove it
    while(!max($a[0]))array_shift($a);
    // while last row is all zeroes, remove it
    while(!max(end($a)))array_pop($a);
    // while first column is all zeroes, remove it
    while(!max(array_map(reset,$a)))array_walk($a,array_shift);
    // while last column is all zeroes, remove it
    while(!max(array_map(end,$a)))array_walk($a,array_pop);
}
```
[Answer]
# [Clean](https://github.com/Ourous/curated-clean-linux), 73 bytes
```
import StdEnv,StdLib
$ =dropWhile(all((>)1))o reverse o transpose
```
# 
```
$o$o$o$
```
[Try it online!](https://tio.run/##bY4xC8IwEIX3/ooDO7RQoSKOddJB6NbBoXSI6VUDyV1I0oJ/3ihWKYK8B4/v3Q1PahQUDfejRjBCUVTGsgvQhP5IU/GKWl2SFKresT3flMZMaJ1l@3yT5wwOJ3QegSE4Qd6yx9gE4UKygmEkGRQTVJDyW0m1lG1bFvBxV8BC2x/63nZ/Psuuiw85aHH1cX2q4@FOwig5w7z8CQ "Clean – Try It Online")
Very similar to [Laikoni's Haskell answer](https://codegolf.stackexchange.com/questions/169366/remove-surrounding-zeroes-of-a-2d-array#169389).
[Answer]
# [Python 2](https://docs.python.org/2/), 86 bytes
```
lambda a,l=1:a if l>4else([a.pop()for b in a if sum(a[-1])<1],f(zip(*a[::-1]),l+1))[1]
```
[Try it online!](https://tio.run/##hVLRUoMwEHznK@4x0ej0atWWEX8k5iEdychMChmSPujPIxeoNJRaJsMky@7t5jj3Hb6aet2Z4qOz@rD/1KCFLTDXUBmw75vS@pJJ/egax7hpWthDVUP86o8HpuUDKv6GShj2Uzl2p2WeEyTsPXIuUXWh9MFDATKD/mFSrgRMSwmYAJwDhE0ADmvOWClC5IU@Ek@aPtGlf1LpKa07np4XmJPhTEbbk@DMsA@wHombWPGFtq8CtgJ2Q60blJvhlwJeVeGVVv5FWW4aJk7Lp6FCNBleaRvObMcbp78pms5C/MvlmcoyGkuaMgFt6Y820ITGqcujtWurOoBhBPHuFw "Python 2 – Try It Online")
Takes a list of lists, returns a list of tuples.
## Explanation
Abuses the heck out of list comprehension. This is the equivalent expanded code:
```
def f(a,l=1):
    # after 4 rotations, the list is back in its original orientation, return
    if l > 4:
        return a
    else:
        # helper variable to store return values
        ret = []
        # "trim" all rows from "bottom" of list that only contain 0s
        # since we are always checking le that item in the list, don't need range(len(a))
        # since we are only removing at most one item per iteration, will never try to remove more than len(a) items
        # brackets surrounding generator force it to be consumed make a list, and therefore actually pop() list items
        ret.append([a.pop() for b in a if sum(a[-1]) < 1])
        # rotate the array, increase the number of rotations, and recursively call this function on the new array/counter
        ret.append(f(zip(*a[::-1]), l + 1)))
        # we only put both items in a list in order to stay in the one-line lambda format
        # discard the popped items and return the value from the recursive call
        return ret[1]
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt) `-h`, ~~23~~ 11 bytes
```
4Æ=sUb_dÃ z
```
[Try it](https://ethproductions.github.io/japt/?v=1.4.6&code=NMY9c1ViX2TDIHo=&input=W1swLCAwLCAwLCAwXSwgWzAsIDAsIDAsIDNdLCBbMCwgMCwgMCwgMF0sIFswLCA1LCAwLCAwXSwgWzAsIDAsIDAsIDBdXQotaFE=)
---
## Explanation
```
                :Implicit input of 2D-array U
4Æ              :Map the range [0,4)
   s            :  Slice U from
    Ub          :   The first index in U where
      _dÃ       :    Any element is truthy (not zero)
          z     :  Rotate 90 degrees
  =             :  Reassign to U for the next iteration
                :Implicitly output the last element
```
]