Minimal cost path in wall-breaking maze Inspired by this Puzzling challenge.
Challenge
Given a 2D rectangular grid where each cell is either an empty space or a wall, find the path (or one of the paths) from the top left cell to the bottom right, which satisfies the following:

Only movement to one of four adjacent cells is allowed.
The path breaks (or passes through) the minimal number of walls possible. In other words, a longer path that breaks fewer walls is preferred over a shorter path that breaks more walls.
Among all paths that satisfy 2., the path is the shortest in terms of the number of cells visited in total.

The input can be taken as a matrix (or any equivalent) containing two distinct values to represent empty spaces and walls. The top left and bottom right cells are guaranteed to be empty.
Output the path as a grid (of the same dimensions as the input) containing two distinct values, one for the cells that are part of the path and the other for the rest.
Standard code-golf rules apply. Shortest code in bytes wins.
Test cases
In the following examples, the input uses .# for empty/wall, and the output uses .+ for non-path/path.
Input
..#..#..

Output
++++++++


Input
.#...
...#.

Output
+.+++
+++.+


Input
....
....
....
....

Output
++++
...+
...+
...+ (or any other path of same length)


Input
..#..
..#..
..#..

Output
+++++
....+
....+ (or any other path of same length that breaks only one walls)


Input
.#.#.
##.##
.###.

Output
+++++
....+
....+ (or 3 other possible answers)


Input
.......
######.
.......
.######
....#..

Output
+++++++
......+
......+
......+
......+


Input
.....#..
#######.
#######.
........
.#######
.#######
....#...

Output
++++++++
.......+
.......+
++++++++
+.......
+.......
++++++++
JavaScript (ES7),  198 185 179  178 bytes
Expects a matrix of integers with -1 for a wall and 0 for an empty cell. Returns a matrix of Boolean values.

m=&gt;(g=(Y,w,n,X)=&gt;w&gt;=W&amp;&amp;w&gt;W|n&gt;N?0:m[Y+1]||1/m[Y][X+1]?m.map((r,y)=&gt;r.map((v,x)=&gt;v&gt;0?1:(X-x)**2+(Y-y)**2^1?0:r[r[x]=1,g(y,w-v,-~n,x),x]=v)):o=g(-1,W=w,N=n))(0,0,W=++m[0][0]/0,0)&amp;&amp;o

Try it online!
Commented
This is a depth-first search. Visited cells are marked with 1. We keep track of the number of broken walls in w and the total number of visited cells in n. We abort as soon as the current path is worse than the best path found so far.
m =&gt; (                         // m[] = input matrix
  g = (                        // g is a recursive function taking:
    Y, w, n, X                 //   (X, Y) = current position
                               //   w = number of broken walls
  ) =&gt;                         //   n = number of visited cells
  w &gt;= W &amp;&amp; w &gt; W | n &gt; N ?    // if (w, n) is worse than (W, N):
    0                          //   abort
  :                            // else:
    m[Y + 1] ||                //   if there's a cell below the current cell
    1 / m[Y][X + 1] ?          //   or a cell on the right:
      m.map((r, y) =&gt;          //     for each row r[] at position y in m[]:
        r.map((v, x) =&gt;        //       for each value v at position x in r[]:
          v &gt; 0 ?              //         if v is positive:
            1                  //           yield 1
          :                    //         else:
            (X - x) ** 2 +     //           if the squared distance between
            (Y - y) ** 2 ^ 1 ? //           (X, Y) and (x, y) is not equal to 1:
              0                //             do nothing
            :                  //           else:
              r[r[x] = 1,      //             mark r[x] as visited by setting it to 1
                g(y, w - v,    //             do a recursive call at (x, y) with n+1
                  -~n, x),     //             if v = -1, w is also incremented
                x              //             actual index ...
              ] = v            //             ... to restore r[x] to v afterwards
        )                      //       end of inner map()
      )                        //     end of outer map()
    :                          //   else (bottom-right cell):
      o = g(-1, W = w, N = n)  //     update (W, N) and use a last recursive call
                               //     with X undefined and Y=-1 to build the output o
)(0, 0, W = ++m[0][0] / 0, 0)  // initial call to g at (0, 0); set the cell at (0, 0)
                               // to 1 and set W to +inf
&amp;&amp; o                           // return o

The purpose of the last recursive call o = g(-1, W = w, N = n) is to create a copy of the current maze where all visited cells are marked with true and all other cells are marked with false.
For this call, it's important to notice that:

because W = w and N = n, the abort test is always false
because Y = -1, the test on m[Y + 1] is always true
because X is undefined, the squared distance is always NaN

Therefore, what is actually done is simply:
m.map((r, y) =&gt; r.map((v, x) =&gt; v &gt; 0 ? 1 : 0))