Here is a way using a JavaScript library. You have to set the same column widths in order to get a perfect match.
library(shiny)
library(DT)
library(dplyr)    
js <- "
var myInterval = setInterval(function() {
  var containers = $('.dataTables_scroll');
  if (containers.length === 2) {
    clearInterval(myInterval);
    containers.scrollsync();
  }
}, 200);
"
CSS <- "
.dataTables_info {
  margin-top: 20px;
}
.dataTables_scrollBody {
  overflow-x: hidden !important;
  width: fit-content !important;
}
.dataTables_scrollHead {
  width: fit-content !important;
}
.dataTables_scroll {
  overflow-x: scroll;
}
table.dataTable {
  table-layout: fixed;
}
"
ui <- fluidPage(
  
  tags$head(
    tags$script(src = "https://cdn.jsdelivr.net/gh/zjffun/jquery-ScrollSync/dist/jquery.scrollsync.js"),
    tags$script(HTML(js)),
    tags$style(HTML(CSS))
  ),
  
  fluidRow(
    DTOutput("setosa_table")
  ),
  
  br(),
  
  fluidRow(
    DTOutput("virginica_table")
  )
  
)
server <- function(input, output) {
  
  # Data
  data <- iris %>%
    mutate(Species = as.factor(Species))
  
  setosa_data <- t(data.frame(data %>%
                                filter(iris$Species == 'setosa'))
  )
  
  virginica_data <- t(data.frame(data %>%
                                   filter(iris$Species == 'virginica'))
  )
  
  # Data Table Outputs
  output$setosa_table <- renderDT({
    datatable(setosa_data,
              extensions = 'FixedColumns',
#              callback = JS(js),
              options = list(
                scrollX = TRUE, 
                fixedColumns = list(
                  leftColumns = 1, 
                  rightColumns = 0
                ),
                columnDefs = list(
                  list(targets = "_all", width = "100px")
                )
              )
    )
  })
  
  output$virginica_table <- renderDT({
    
    datatable(virginica_data,
              extensions = 'FixedColumns',
              options = list(
                scrollX = TRUE, 
                fixedColumns = list(
                  leftColumns = 1, 
                  rightColumns = 0
                ),
                columnDefs = list(
                  list(targets = "_all", width = "100px")
                )
              )
    )
  })
  
}
# Run the application 
shinyApp(ui = ui, server = server)
EDIT
The following map automatically sets each column width to the maximum of the two widths of this column in the two initial tables. Therefore the column widths are equal in an optimal way.
library(shiny)
library(DT)
library(dplyr)
js <- "
var iScrollSync = setInterval(function() {
  var containers = $('.dataTables_scroll');
  var tables = containers.find('table');
  if (tables.length === 4) {
    clearInterval(iScrollSync);
    containers.scrollsync();
  }
}, 200);
var widths = [];
$(document).on('preInit.dt', function(e, settings){
  var api = new $.fn.dataTable.Api(settings);
  var iGetWidths = setInterval(function(){
    var w = $(api.table().header()).find('th').map(function(i,x){return $(x).width();}).get();
    if(w[0] > 0){
      clearInterval(iGetWidths);
      widths.push(w);
    }
  }, 5);
  var iSetWidths = setInterval(function(){
    if(widths.length === 2){
      clearInterval(iSetWidths);
      var maxwidths = widths[0].map(function(w,i){return Math.max(w, widths[1][i]);});
      var dtBody = $(api.table().node()).closest('.dataTables_scrollBody');
      var ths_body = dtBody.find('th');
      ths_body.each(function(index,item){$(item).width(maxwidths[index]);});
      var ths_header = dtBody.parent().find('.dataTables_scrollHead').find('th');
      ths_header.each(function(index,item){$(item).width(maxwidths[index]);});
      api.on('order.dt', function(){
        var ths_body = dtBody.find('th');
        ths_body.each(function(index,item){$(item).width(maxwidths[index]);});
        ths_header.each(function(index,item){$(item).width(maxwidths[index]);});
      });
    }
  }, 5);
});
"
CSS <- "
.dataTables_info {
  margin-top: 20px;
}
.dataTables_scrollBody {
  overflow-x: hidden !important;
  width: fit-content !important;
}
.dataTables_scrollHead {
  width: fit-content !important;
}
.dataTables_scroll {
  overflow-x: scroll;
}
table.dataTable {
  table-layout: fixed;
} 
"
ui <- fluidPage(
  
  tags$head(
    tags$script(src = "https://cdn.jsdelivr.net/gh/zjffun/jquery-ScrollSync/dist/jquery.scrollsync.js"),
    tags$script(HTML(js)),
    tags$style(HTML(CSS))
  ),
  
  fluidRow(
    column(12,
      DTOutput("setosa_table")
    )
  ),
  
  br(),
  
  fluidRow(
    column(
      12,
      DTOutput("virginica_table")
    )
  )
  
)
server <- function(input, output) {
  
  # Data
  data <- iris %>%
    mutate(Species = as.factor(Species))
  
  setosa_data <- t(data.frame(data %>%
                                filter(iris$Species == 'setosa'))
  )
  
  virginica_data <- t(data.frame(data %>%
                                   filter(iris$Species == 'virginica'))
  )
  
  # Data Table Outputs
  output$setosa_table <- renderDT({
    datatable(setosa_data,
              extensions = 'FixedColumns',
              options = list(
                autoWidth = TRUE,
                scrollX = TRUE, 
                fixedColumns = list(
                  leftColumns = 1, 
                  rightColumns = 0
                )
              )
    )
  })
  
  output$virginica_table <- renderDT({
    
    datatable(virginica_data,
              extensions = 'FixedColumns',
              options = list(
                autoWidth = TRUE,
                scrollX = TRUE, 
                fixedColumns = list(
                  leftColumns = 1, 
                  rightColumns = 0
                )
              )
    )
  })
  
}
# Run the application 
shinyApp(ui = ui, server = server)